【问题标题】:Rails where() clause on model association?关于模型关联的 Rails where() 子句?
【发布时间】:2020-03-15 01:54:41
【问题描述】:

假设我有一个拥有多个用户的帐户模型。帐户有一个布尔“活动”列。如何获取属于“活动”帐户的所有用户?

@users_of_active_accounts = User.?

谢谢!

【问题讨论】:

  • 您希望将所有活动帐户的所有用户放在一个平面数组中?

标签: ruby-on-rails


【解决方案1】:

试试这个:

User.joins(:account).where(:accounts => { :active => true })

【讨论】:

  • 一些可能也有帮助的注释:i) .joins(:account) :account 应该是单数还是复数,具体取决于关联(例如 has_one 的单数和 has_many 的复数),ii) .where(:accounts.. 这里accounts 指的是表格,所以总是复数。希望可以为某人节省一两分钟。 (如果我错了,请纠正我)
【解决方案2】:

您需要加入帐户表并合并适当的帐户范围:

User.joins(:account).merge(Account.where(:active => true))

【讨论】:

  • 如果你有一个命名范围,你也可以使用,例如User.joins(:account).merge(Account.active)
  • 太棒了,这将是我的下一个问题。谢谢!
  • @SimonPerepelitsa 应该是:accounts
【解决方案3】:

在 Account 模型的关联中使用 where 子句:

class Account < ActiveRecord::Base
  has_many :users, -> {where(active: true)}

其他查询也可以,但如果您始终只关心活跃用户,则关联级别的过滤将正确封装过滤器,并为您省去日后的麻烦。

更新:

您还可以在同一张表上指定 2 个关系:

 class Account < ActiveRecord::Base
   has_many :users
   has_many :active_users, -> {where(active: true)}, :class_name => 'User'

第二次更新:

重新阅读问题后,我现在看到我的回答没有回答问题。这是我对这个问题的回答:

User.where(account: Account.where(active: true))

第三次更新: 这是一个具有 active_users 属性的示例用户模型

class User < ActiveRecord::Base
  belongs_to :account
  def self.active
    where(account: Account.where(active: true))
  end
end

这样做可以让您将其与其他用户查询内联:

User.active.where(created_at: (1.week.ago..0.day.ago)).count

【讨论】:

  • 在模态中我如何通过这里也添加订单 has_many :users, -> {where(active: true)}
  • 可以直接在where函数后面加上:has_many :users, -> {where(active: true).order(:name)}。基本上任何活动记录查询都可以放在该闭包中,但由于范围的原因,使用变量可能会很棘手。有一种方法可以传入范围以便能够在关联中使用变量。不过不确定文档在哪里。
  • 我相信第三次更新可以写成一个范围。 scope :active, -&gt; { where(account: Account.where(active: true)) }
  • 谢谢@evanthegrayt,我对rails 的那部分不太熟悉。我得调查一下。
  • 有用的文章审查范围:rubyguides.com/2019/10/scopes-in-ruby-on-rails
【解决方案4】:

试试这个:

Account.includes(:users).where(active: true)

【讨论】:

    【解决方案5】:

    可以做到这一点的宝石:activerecord_where_assoc(我是作者)

    有了它,你可以用这种方式做你想做的事:

    @users_of_active_accounts = User.where_assoc_exists(:account, active: true)
    

    如果您在 Account for active 上有一个范围,您可以这样称呼它:

    @users_of_active_accounts = User.where_assoc_exists(:account, &:active)
    

    所以现在,如果你愿意,你可以为此创建一个不错的范围:

    class User < ActiveRecord::Base
      belongs_to :account
    
      scope :active_account, -> { where_assoc_exists(:account, active: true) }
    end
    
    @users_of_active_accounts = User.active_account
    

    documentation 中了解更多信息。这是introductionexamples

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-22
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多