2008-09-17 59 views
6

我有两个表加入了连接表 - 这仅仅是伪代码:的Ruby/Rails收藏到收藏

Library 
Book 
LibraryBooks 

我需要做的是,如果我有一个库的ID,我想以获得该图书馆所有图书的所有图书馆。

因此,如果我有图书馆1,图书馆1有书籍A和B,书籍A和B在图书馆1,2,和3,有没有一种优雅的(一条线)方式来解决这个问题?

我在想:

l = Library.find(1) 
allLibraries = l.books.libraries 

但是,这似乎并没有工作。建议?

+0

所以你想要所有的图书馆有书吗?上面的代码片段不会仅仅返回与l相同的库。它就像问你所有的书,他们的主人是谁,是你。一点儿混乱......但下面的吉姆的答案会做排序技巧。 – Gishu 2008-09-17 03:55:42

+0

所有图书馆都有图书馆,是吗? – 2008-09-17 04:04:06

+0

@Jim - 这正是我想要的 – aronchick 2008-09-24 23:36:40

回答

7
l = Library.find(:all, :include => :books) 
l.books.map { |b| b.library_ids }.flatten.uniq 

注意map(&:library_ids)比红宝石1.8.6 map { |b| b.library_ids }较慢,而在1.9.0更快。

我还要提到的是,如果你使用的:joins代替include有,它会找到库和相关书籍都在同一个查询加快数据库的时间。但是如果图书馆有图书,:joins只能使用。

3

也许:

l.books.map {|b| b.libraries} 

l.books.map {|b| b.libraries}.flatten.uniq 
如果你想这一切在一个平面阵列

当然,你应该真的把它定义为图书馆的一种方法,以维护封装的崇高事业。

2

如果您想要返回一个库的一维数组,并删除了重复项。与

l.books.map{|b| b.libraries}.flatten.uniq 

l.books.map{|b| b.libraries}.flatten.uniq 
2

的一个问题是,它会生成一个SQL调用每本书交运集团。更好的方法(假设我理解你的架构)可能是:

LibraryBook.find(:all, :conditions => ['book_id IN (?)', l.book_ids]).map(&:library_id).uniq