has_many:当连接表不包含FK到两个表时

时间:2011-01-14 02:40:56

标签: ruby-on-rails ruby-on-rails-3 activerecord

我的结构实际上不是has_many :through示例,但我希望它表现得像:

# user.rb
belongs_to :blog
has_many :posts

# post.rb
belongs_to :user

# blog.rb
has_many :users
has_many :posts, :through => :users  # this obviously doesn't work becase
                                     # both FKs aren't in the blogs table

我想在数组中获取博客的所有帖子。我知道我可以使用each或者使用collect来使用Ruby来实现这一点,但我想让SQL完成这项工作。

有人可以解释我如何设置我的模型,让我用SQL和Ruby调用@ blog.posts,并解释哪种方式“更好”?

修改

我在SQL中知道我可以编写类似的内容:

SELECT * FROM posts WHERE posts.user_id IN (
  SELECT users.id FROM users WHERE users.blog_id = 7
)

显然需要两个查询。我不认为这可能是join,但我不完全确定。很明显需要子查询,但是我如何使用ARel来构建子查询,而不必返回并使用Ruby来循环和收集等等?

1 个答案:

答案 0 :(得分:2)

尝试将其放入Post模型

scope :for_blog, lambda{|blog|
  where("user_id IN (SELECT u.id FROM users u WHERE u.blog_id = ?)", blog.id)
}

这样您就可以拨打Post.for_blog(@blog)了。 SQL返回的对象必须转换为Post s(这就是为什么我将范围放在Post模型中)。

然后,在您的Blog模型中,输入

def posts
  Post.for_blog(self)
end

通过定义虚拟属性,您现在应该可以通过@blog.posts访问博客的帖子了。