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
因此,在这个示例中,我想显示所有流派的列表,但第一列应该是类型。因此,如果说流派是“Space”,则类型可以是“Non-fiction”和“Fiction”,并且它将显示:
Type Genre
Fiction Space
Non-fiction Space
流派表只有“id”、“name”和“description”,连接表genredes_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 :through 吗?
I am trying to get a list, and I will use books as an example.
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
So in this example I want to show a list of all Genres, but it the first column should be the type. So, if say a genre is "Space", the types could be "Non-fiction" and "Fiction", and it would show:
Type Genre
Fiction Space
Non-fiction Space
The Genre table has only "id", "name", and "description", the join table genres_books has "genre_id" and "book_id", and the Book table has "type_id" and "id". I am having trouble getting this to work however.
I know the sql code I would need which would be:
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
and I found I could do
@genre = Genre.all
@genre.each do |genre|
@type = genre.book.find(:all, :select => 'type_id', :group => 'type_id')
@type.each do |type|
and this would let me see the type along with each genre and print them out, but I couldn't really work with them all at once. I think what would be ideal is if at the Genre.all statement I could somehow group them there so I can keep the genre/type combinations together and work with them further down the road. I was trying to do something along the lines of:
@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] )
But at this point I am running around in circles and not getting anywhere. Do I need to be using has_many :through?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下示例使用上面定义的模型。您应该使用范围将关联推回到模型中(或者您可以只在模型上定义类方法)。这有助于控制您的记录获取呼叫,并帮助您遵守德米特定律。
获取书籍列表,无条件地急切地加载每本书的类型和流派:
一旦你有了这个列表,如果我理解你的目标,你可以做一些 in-Ruby 分组,将你的书籍纳入你需要传递到的结构中你的观点。
The following examples use your models, defined above. You should use scopes to push associations back into the model (alternately you can just define class methods on the model). This helps keep your record-fetching calls in check and helps you stick within the Law of Demeter.
Get a list of Books, eagerly loading each book's Type and Genres, without conditions:
Once you have that, if I understand your goal, you can just do some in-Ruby grouping to corral your Books into the structure that you need to pass to your view.