2011-07-06 36 views
0

我想獲得一個列表,我將以書籍爲例。Rails HABTM加入另一個條件

class Book < ActiveRecord::Base 
    belongs_to :type 
    has_and_belongs_to_many :genres 
end 

class Genre < ActiveRecord::Base 
    has_and_belongs_to_many :books 
end 

所以在這個例子我想告訴所有類型的列表,但是它的第一列應該是類型。所以,如果說一個流派是「空格」,該類型可以是「非小說」與「小說」,它會顯示:

Type   Genre  
Fiction  Space 
Non-fiction Space 

文體表只有「ID」,「姓名」,和「描述」中,連接表genres_books具有「genre_id」和「book_id」,並且Book表具有「type_id」和「id」。然而,我卻遇到了麻煩。

我知道SQL代碼,我需要具體做法是:

SELECT distinct genres.name, books.type_id FROM `genres` INNER JOIN genres_books ON genres.id = genres_books.genre_id INNER JOIN books ON genres_books.book_id = books.id order by genres.name 

,我發現我可以做

@genre = Genre.all 
@genre.each do |genre| 
    @type = genre.book.find(:all, :select => 'type_id', :group => 'type_id') 
    @type.each do |type| 

,這將讓我看到的類型,每個類型和打印沿他們出去了,但我無法一次真正地與他們一起工作。我認爲如果在Genre.all聲明中我可以將它們分組在一起,那麼我可以將這些流派/類型組合在一起,並在更遠的路上與它們一起工作。我試圖做一些沿線:

@genres = Genre.find(:all, :include => :books, :select => 'DISTINCT genres.name, genres.description, books.product_id', :conditions => [Genre.book_id = :books.id, Book.genres.id = :genres.id]) 

但在這一點上,我在圈子裏跑來跑去,沒有得到任何地方。我需要使用has_many:通過嗎?

回答

1

以下示例使用上面定義的模型。您應該使用範圍將關聯推回到模型中(或者您可以在模型上定義類方法)。這有助於保持記錄取回的電話,並幫助您遵守德米特法。

獲取書籍的列表,急切地加載每本書的類型和流派,沒有條件:

def Book < ActiveRecord::Base 
    scope :with_types_and_genres, include(:type, :genres) 
end 

@books = Book.with_types_and_genres #=> [ * a bunch of book objects * ] 

一旦你的,如果我理解你的目標,你可以做一些德勝分組才逮住您的圖書放入您需要傳遞給您的視圖的結構中。

@books_by_type = @books.group_by { |book| book.type } 

# or the same line, more concisely 
@books_by_type = @books.group_by &:type 

@books_by_type.each_pair do |type, book| 
    puts "#{book.genre.name} by #{book.author} (#{type.name})" 
end