【问题标题】:Query has_many through association Rails通过关联 Rails 查询 has_many
【发布时间】:2013-05-21 11:45:19
【问题描述】:

我有一个 has_many 虽然这样的关联:

User.rb
has_many :memberships, :dependent => :destroy

has_many :groups, :through => :memberships

Group.rb
has_many :users, :through => :memberships
has_many :microposts


Membership.rb
belongs_to :user
belongs_to :group

首先我需要知道查询以获取用户的所有组,然后我需要一种方法来显示这些组的所有微博。是否可以通过该信息获得一个查询?

非常感谢!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 has-many-through


    【解决方案1】:

    获取用户组:

    some_user = User.find(some_id)
    some_user.groups
    

    要获得微博,你可以这样做:

    some_user.groups.each do |group|
      puts group
      puts group.microposts
    end
    

    但是,这会导致生成单独的查询来收集每个组的微博。这可以通过使用includes 预先加载微博来解决:

    some_user.groups.includes(:microposts).each do |group|
      puts group
      puts group.microposts
    end
    

    现在只会生成 2 个查询 - 一个用于获取组,一个用于获取与这些组关联的 所有 个微博。在后台,ActiveRecord 会将微博匹配到正确的群组,并在群组上调用.microposts 时相应地返回它们。

    要获取所有微博作为哈希,您可以使用each_with_object 收集它们:

    @group_microposts = some_user.groups.includes(:microposts).
                                  each_with_object({}){|group, h| h[group] = group.microposts}
    

    这将返回{ group => microposts } 形式的哈希。

    要将它们作为数组获取,您可以这样做:

    @microposts = some_user.groups.includes(:microposts).map(&:microposts).flatten
    

    但是,如果您根本不需要组信息,还有一种更有效的方法:

    @microposts = Micropost.joins(:group => :users).where(:users => {id: some_user.id})
    

    第二种方法更快有两个原因 - 它只需要一个查询(不需要急切加载)并且数据库查找更有效,因为它可以使用可用索引来执行必要的连接而不是过滤文字整数列表(随着列表变大会变慢)。

    【讨论】:

    • 谢谢!如何将属于用户的所有组的所有微帖子保存在实例变量中?所以在我看来,我可以使用@microposts 或类似的东西......
    • 您需要将它们按group 分组还是仅仅作为一大堆微博?
    • 两个选项都更新了 ;)
    • 哇!我该如何订购?顺便说一句,我使用了最后一个选项,例如条件,创建于或类似的东西..
    • 最后使用.order(:created_at)。如果您需要更复杂的逻辑,可以使用 SQL ORDER BY 子句中可接受的任何字符串:.order("groups.created_at, microposts.created_at, microposts.id DESC")
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多