2011-01-14 42 views
1

我有一个结构,它是不是一个真正的has_many :through例子,但我想它表现得像一个:的has_many:通过当连接表中不包含FK两个表

# 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 

我想获取数组中博客的所有帖子。我知道我可以用Ruby来做到这一点,使用each或喜欢collect,但我想让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,但我不完全确定。很明显,需要一个子查询,但我如何获得rails来使用ARel构建子查询,而不必返回并使用Ruby进行循环和收集等等。

回答

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(这就是为什么我会将范围放在Post模型中)。

然后,在你Blog模型,把

def posts 
    Post.for_blog(self) 
end 

通过定义虚拟属性,你现在应该能够通过@blog.posts访问博客帖子。

+0

这个工作,如果我访问其他关系的职位?就像我需要做post.versions(另一张桌子)和其他东西.. – sethvargo 2011-01-14 03:01:19

相关问题