Active Record关系方法聚合关联的has_many

时间:2018-11-19 22:02:52

标签: ruby-on-rails ruby activerecord

考虑以下两个模型:

class User < ApplicationRecord
  has_many :blogs
end

class Blog < ApplicationRecord
  belongs_to :user
end

我想做这样的事情,但是不起作用:

my_users        = User.where(age: 35) 
all_assoc_blogs = my_users.blogs # errors out

这是错误:

  

User :: ActiveRecord_Relation的未定义方法“ blogs”:

我知道为什么它不起作用:您只能在单个blogs对象上调用user。您不能在blogs的活动记录关系对象上调用users

最终,我想要一个活动记录关系对象,该对象由my_users活动记录关系对象中所有用户的所有博客的集合组成。有一个光滑的方法可以做到这一点吗?这是我唯一能想到的方法,而且非常难看:

my_users   = User.where(age: 35)
temp_blogs = []
my_users.each {|u| temp_blogs << u.blogs.to_a}
blog_ids = temp_blogs.flatten.pluck(:id)
Blog.where(id: blog_ids)

4 个答案:

答案 0 :(得分:1)

活动记录,Metrodome会向您返回活动记录关系,而不是唯一结果。您需要:

my_users = User.where(age: 35).first

那么您应该能够通过以下方式获得一个用户的博客:

my_users.blogs

但是,如果您打算拥有所有不同用户的博客,则应该尝试:

my_user_ids = User.where(id: 35).pluck(:id)
Blog.where(user_id: my_user_ids)

答案 1 :(得分:1)

也许会帮助您:

Blog.joins(:user).where(user: User.where(age: :35))

Blog.joins(:user).merge(User.where(age: :35))

答案 2 :(得分:0)

这就是我想要的:

my_users = User.where(age: 35)
Blog.where(user: my_users)

让我绊倒的是我不得不换档。我首先获取了相关的users,但是随后将那些users传递到了Blog查询中。

由于我最终想要一个有效的记录关系blogs,所以最干净的方法是确保在查询中开始使用的顶级模型是Blog

答案 3 :(得分:0)

其他答案是正确的,但是您可以更有效地执行此操作,并减少数据库查询。

my_users = User.includes(:blogs).where(age: 35)  # this makes one db query to get all data
all_assoc_blogs = my_users.map(&:blogs)