You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何省略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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 17:22:48