如何在Rails中基于联接表作用域检索关联

问题描述 投票:0回答:1

我有三种模型,用户,注册人,程序。

注册人是用户和程序之间的联接表,包含user_idprogram_idstatus,这是一个枚举。

class User < ApplicationRecord
    has_many :registrants, dependent: :destroy
    has_many :programs, through: :registrants
end
class Registrant < ApplicationRecord
    belongs_to :user
    belongs_to :program

    enum status: {
        enrolled: 1,
        unenrolled: 2,
        instructor: 3,
        passed: 4,
        failed: 5
    }

    scope :active, -> { where(status: [:enrolled, :instructor]) }
end
class Program < ApplicationRecord
    has_many :registrants, dependent: :destroy
    has_many :users, through: :registrants
end

我希望只能从连接表中检索枚举状态为:enrolled或:instructor的记录,以便我可以执行以下操作:

program.registrants.active.users

我该如何完成?

ruby-on-rails join associations
1个回答
0
投票

由于program.registrants.active.users,应避免使用像Law of Demeter这样的长链,所以这不是一个好目标。

您可以通过传递哈希将条件添加到.where中的联接表:

program.users.where(
  registrants: { status: [:enrolled, :instructor] }
)

请注意,键应该是表名(或其在查询中的别名),而不是关联的名称。

您还可以传递范围:

program.users.where(Registrant.active)

您还可以通过创建“作用域”关联来清理此问题:

class Program < ApplicationRecord
    has_many :registrants, dependent: :destroy
    has_many :users, through: :registrants
    has_many :active_users, 
             through: :registrants,
             source: :user,
             -> { where(Registrant.active) }

end

谁会让您打电话:

program.active_users # Demeter is happy.
© www.soinside.com 2019 - 2024. All rights reserved.