我怎样才能访问的has_many:通过关联对象的相关加盟模式,无需额外的查询? [英] How can I access a has_many :through association object's relevant join model without additional queries?

查看:77
本文介绍了我怎样才能访问的has_many:通过关联对象的相关加盟模式,无需额外的查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我已经遇到了很多次,现在我很想无论是弄清楚如何做我想要或建立并提交了一个补丁,Rails的,做它。在我的应用程序很多时候,我有一些模型,看起来像这样:

This is something I've come across a number of times now and I'd love to either figure out how to do what I'm wanting or build and submit a patch to Rails that does it. Many times in my apps I'll have some models that look something like this:

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中,让这样的东西?因为唯一的方法,我知道要实现的结果我说的是非常丑陋和低效的,是这样的:

Is there anything in Rails that allows this? Because the only methods I know to achieve the result I'm talking about are terribly ugly and inefficient, something like this:

@group.users.each do |user|
  membership = Membership.where(group_id: @group.id, user_id:user.id).first
end

是否ActiveRecord的有一些神秘的内置工具来实现这一目标?现在看来似乎不会太硬,它已经有来获取加盟模式,以便正确地获取协会反正因此,如果此功能不存在,在我看来,它应该。我碰到的这个很多次,并已经准备好卷起衣袖和解决为好。我该怎么办?

Does ActiveRecord have some arcane in-built facility to achieve this? It seems like it wouldn't be too hard, it's already having to fetch the join model in order to properly retrieve the association anyway so if this functionality doesn't exist it seems to me it should. I've run into this a number of times and am ready to roll up my sleeves and solve it for good. What can I do?

更新:其他图案这一点,我可以使用,基本上得到我要的是这样的:

Update: The other pattern for this that I could use that basically gets what I want is something like this:

@group.memberships.includes(:user).each do |membership|
  user = membership.user
end

但在美学我不喜欢这样的解决方案,因为我没有真正感兴趣的这么多的成员,因为我的用户,并感到不对劲进行遍历加盟模式,而不是协会的目标。但是,这是比我上文所指出的(感谢杨叙Intridea的提醒这一个我)的另一种方式更好。

But aesthetically I don't like this solution because I'm not actually interested in the memberships so much as I am the users and it feels wrong to be iterating over the join model instead of the association target. But this is better than the other way I pointed out above (thanks to Ian Yang of Intridea for reminding me of this one).

推荐答案

如果你只是想访问的成员的某些属性,有一个丑陋的伎俩

If you just want to access some attributes in membership, there is an ugly trick

group.users.select('*, memberships.some_attr as membership_some_attr')

它的工作原理,因为成员包括在暗中JOIN。

It works because memberships is included in JOIN implicitly.

更新

更重要的是,如果你在用户添加一个丑陋的伎俩

What's more, if you add another ugly trick in 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

这篇关于我怎样才能访问的has_many:通过关联对象的相关加盟模式,无需额外的查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆