如何省略voter_memberships关联,仍让voters关联正常工作?
解决方案
报错原因
你写的-> { voter }是作用在User模型的查询集合上的,但voter是Membership模型里定义的enum scope方法,User模型根本没有这个方法,所以会报“undefined local variable or method 'voter'”的错误。
正确写法
要直接通过memberships关联筛选出对应角色的用户,有两种可靠方式:
方式一:用merge结合Membership的enum scope(推荐)
利用Rails的merge方法,把Membership模型中定义的enum scope合并到用户查询里,这样既符合enum的最佳实践,后续enum值变化时也不用修改这段代码:
class Team belongs_to :owner, class_name: "User" has_many :memberships has_many :members, through: :memberships, source: :user, class_name: "User" # 直接通过memberships筛选voter角色的用户 has_many :voters, -> { merge(Membership.voter) }, through: :memberships, source: :user, class_name: "User" end
方式二:直接指定where条件
如果觉得merge不够直观,也可以直接在lambda里写where条件,明确指定memberships表的role字段值:
class Team belongs_to :owner, class_name: "User" has_many :memberships has_many :members, through: :memberships, source: :user, class_name: "User" has_many :voters, -> { where(memberships: { role: :voter }) }, through: :memberships, source: :user, class_name: "User" end
批量处理其他角色
对于contributor、editor、manager这些角色,你可以用完全相同的逻辑批量处理,不用再单独定义xxx_memberships关联:
class Team belongs_to :owner, class_name: "User" has_many :memberships has_many :members, through: :memberships, source: :user, class_name: "User" has_many :voters, -> { merge(Membership.voter) }, through: :memberships, source: :user, class_name: "User" has_many :contributors, -> { merge(Membership.contributor) }, through: :memberships, source: :user, class_name: "User" has_many :editors, -> { merge(Membership.editor) }, through: :memberships, source: :user, class_name: "User" has_many :managers, -> { merge(Membership.manager) }, through: :memberships, source: :user, class_name: "User" end
内容的提问来源于stack exchange,提问作者anithri
相关产品推荐
相关产品推荐

