Rails加入(包括)belongs_to模型

时间:2012-09-11 13:13:02

标签: ruby-on-rails activerecord

我有一个模型用户,有很多照片。

我需要获取用户Feed(来自其他用户的照片,应该包含用户),因此查询将是:

Photo.where(:user_id => Relationship.select(:followed_id).where(:follower_id => user.id)<<user.id).joins(:user)

但我只收到照片,没有用户信息。是否可以进行返回类似的查询:

({user:{},photo:{}},{user:{},photo:{}},{user:{},photo:{}})

2 个答案:

答案 0 :(得分:3)

这里要理解的重要一点是,通过使用includes,rails直接从数据库返回原始模型(在本例中为Photo),但也可以将所有相关的用户模型加载到内存中,这些用户模型可以通过照片查询。这种方法假设DB查询时间很长,并且花费内存空间/ CPU时间更有效。

实际上,这意味着在您执行查询后:

@photos = Photo.where(:user_id => Relationship.select(:followed_id).where(:follower_id => user.id)<<user.id).includes(:user)

你可以运行:

@photos.first.user

这不会转到用户的数据库,而是从内存中加载(这被认为是便宜的)。因此,当您需要照片的用户时,只需运行其user方法,您就不必在({user:{},photo:{}},{user:{},photo:{}},{user:{},photo:{}})结构中对其进行预先组织 - 只需在需要时加载用户它

如果由于某种原因你必须以这种特定的方式组织它,你可以:

@photos = Photo.where(:user_id => Relationship.select(:followed_id).where(:follower_id => user.id)<<user.id).includes(:user)

@photos = @photos.map {|p| {:user => p.user, :photo => p}

这将返回包含照片和用户哈希值的数组。

答案 1 :(得分:0)

根据您的评论,您可能需要一个级别的链式查询,因为应该按照原始帖子将结果传递给另一个方法。这是完全未经测试的,但我认为这是你需要实现的方向。我们的想法是获得当前用户所关注的所有关系对象。然后,您包含名为follower的用户对象。可能需要更改该符号,具体取决于您在关系模型中定义belongs_to的方式。从那里你包括照片。

根据生成的查询,它可能会抛出错误。如果是,请将符号切换为字符串,指定表名称。如果您在尝试此操作时遇到错误,请使用堆栈跟踪编辑您的问题。

Relationship.where(:follower_id => user.id).includes(:follower).includes(:photos)