【问题标题】:Ruby on Rail - Check if at least 2 records with my condition exsistRuby on Rail - 检查是否存在至少 2 条符合我条件的记录
【发布时间】:2016-04-30 16:29:40
【问题描述】:

在我的应用程序中,如果存在 2 条具有我/相同条件的记录,我想显示 db 记录?

最有效的检查方法是什么?

这是我的代码:

- if @users.where(friend_group: 0).where(city_id: 2).any?
  - @users.where(user_group: 0).where(city_id: 2).each do |user|
    %p= user.name
    %p= user.city.name

而不是any?,我想检查是否只有 2条条件相同的记录存在时,它可以显示它们。

我试过- if @users.where(friend_group: 0).where(city_id: 2).exist?(2),但没有成功。

ps:我使用的是 rails 4.2

【问题讨论】:

  • 正好两个或至少两个?如果至少有两条,您是要显示所有记录还是只显示其中两条(按什么顺序)?

标签: ruby-on-rails ruby conditional-statements


【解决方案1】:

通常您应该避免在视图中进行数据库查询 - 更好的解决方案是在控制器或模型中进行:

class User < ActiveRecord::Base
  # ...
  def self.by_group_and_city(friend_group, city, threshold: 2)
    scope = User.where(friend_group: friend_group, city: city)
    # if you want only if exactly two records match then use ==
    scope.size >= threshold ? scope : User.none
  end
end

如果没有匹配的记录,我们会返回 User.none 而不是 nil - 这样您就可以安全地在空关系对象上调用像 .each 这样的方法。

- User.by_group_and_city(0, 2).each do |u|
  %p= user.name
  %p= user.city.name

最好让控制器进行查询:

def index
  @nearby_users = User.by_group_and_city(0, 2)
  # ...
end

- @nearby_users.each do |u|
  %p= user.name
  %p= user.city.name

【讨论】:

  • 我建议在这种情况下使用lengthsize 而不是count,因为使用count 将在满足threshold 时进行第二次数据库查询。而length 将加载关系,因此不会触发第二个查询。了解length, size and count 之间的区别
  • 好点@spickermann,我将其更改为大小,然后由 OP 来选择要使用的策略 - 在某些情况下,在计数之前预加载模型可能会更快,但有时是 COUNT 查询 +常规选择更快。
  • @max 谢谢,很好的解决方案,但它不符合我的需求,但我从中学到了很多:)
【解决方案2】:

只需使用活动记录关系的#count,范围索引如下:

- rela = @users.where(friend_group: 0).where(city_id: 2)
- if rela.count > 1
  - rela[0..1].each do |user|
    %p= user.name
    %p= user.city.name

【讨论】:

    猜你喜欢
    • 2021-08-28
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多