2008-09-17 47 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