I am little bit stuck with the following problem. I have two models:
class Book < ActiveRecord:B开发者_JAVA百科ase
has_and_belongs_to_many :tags
end
class Tag < ActiveRecord:Base
has_and_belongs_to_many :books
end
I have a list of specific tags that can but must not be used in the tags table:
tag1, tag2, tag3, tag4, tag5, ...
Each new book can have several tags. As usual, relationships are stored in a join table "books_tags".
How can I get a list of all tags that are at least related to one book?
You can use :joins
as an option in your find call. E.g.
Tag.find(:all, :select => 'distinct tags.*', :joins => :books)
This will only find tags that have a book associated and the :select => 'distinct tags.*'
ensures you only retrieve each tag once even if they are associated with multiple books.
This would probably be easier using the has_many ..., :through
method of joining than the old-fashioned has_and_belongs_to_many
which is generally not as versatile.
A simple way of restructuring this is:
class Book < ActiveRecord:Base
has_many :book_tags
has_many :tags, :through => :book_tags
end
class Tag < ActiveRecord:Base
has_many :book_tags,
has_many :books, :through => :book_tags
end
class BookTag < ActiveRecord::Base
belongs_to :book
belongs_to :tag
end
If you're looking for a list of tags that have at least one book, you can retrieve this using the BookTag model. In this case you're looking for the distinct set of tags from the join list:
SELECT DISTINCT tag_id FROM book_tags
You can wrangle that into a find call easily enough.
You may find an acts_as_taggable type plugin that handles this for you, though.
精彩评论