这是我现在遇到过很多次的事情,我很想知道如何做我想要的或构建并向Rails提交补丁.在我的应用程序中很多次我会有一些看起来像这样的模型:
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, through: :memberships
end
class Membership
belongs_to :user
belongs_to :group
def foo
# something that I want to know
end
end
class Group
has_many :memberships
has_many :users, through: :memberships
end
我希望能够做的是通过调用关联访问相关成员资格而无需进行其他查询.例如,我想做这样的事情:
@group = Group.first
@group.users.each do |user|
membership = user.membership # this would be the membership for user in @group
end
Rails中有什么允许这个吗?因为我所知道的唯一可以实现我所说的结果的方法非常丑陋且效率低下,如下所示:
@group.users.each do |user|
membership = Membership.where(group_id: @group.id, user_id:user.id).first
end
ActiveRecord是否有一些神秘的内置工具来实现这一目标?看起来它不会太难,它已经必须获取连接模型才能正确检索关联,所以如果这个功能不存在,我认为它应该.我已经多次遇到这种情况,并准备好卷起袖子并妥善解决.我能做什么?
更新:我可以使用的其他模式基本上得到我想要的是这样的:
@group.memberships.includes(:user).each do |membership|
user = membership.user
end
但从美学角度来说,我不喜欢这种解决方案,因为我实际上对成员资格并不感兴趣,因为我是用户,迭代连接模型而不是关联目标是错误的.但这比我上面指出的其他方式要好(感谢Intridea的Ian Yang提醒我这个).
最佳答案 如果您只想访问成员资格中的某些属性,那就有一个难看的伎俩
group.users.select('*, memberships.some_attr as membership_some_attr')
它的工作原理是因为成员资格隐式包含在JOIN中.
更新
更重要的是,如果你在User中添加另一个丑陋的技巧
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, through: :memberships
belongs_to :membership #trick, cheat that we have membership_id
end
现在:
group.users.select('*, memeberships.id as membership_id').includes(:membership).each do |user|
membership = user.membership
end