问题
I'm relatively new to Rails and to learn more am trying to build a simple blog. One of the issues I'm running in to is tagging. I have a Tag
model that I am using to create and manage tags that can be applied to posts. I also have a Post
model. I need to be able to associate any of the tags with the post, retrieve them for output, and be able to filter/query posts by a specific tag.
So far I've created a column on Post
called tags
, which gets assigned an array of Tag
IDs, and is then serialized. This works great for retrieval, but my understanding is that trying to query records by their serialized columns is a big no-no.
As the link above recommends, I've done this to achieve my filter:
Post.all.select { |post| post.tags.include? 3 }
But I know that this is gathering all of my posts and then using the array method select
to filter through them.
My question is: how can I associate any number of Tag
records with a Post
record, and query/filter Posts records by a given Tag?
回答1:
So let's assume your models look like this:
class Post < ActiveRecord::Base
has_many :taggings
has_many :tags, through: :taggings
end
class Taggings < ActiveRecord::Base
belongs_to :post
belongs_to :tag
end
class Tag < ActiveRecord::Base
has_many :taggings
has_many :posts, through: :taggings
end
So taggings is the join model that gives you your many-to-many association with tags and posts.
At this point, adding a tag to a post is as simple as:
post.tags << Tag.create(name: 'foo')
You can query this through active record, by using nested hashes in the where.
Post.joins(:tags).where(tags: { name: 'foo' })
Remember that tags here is the name of the relationship we declared in the models, not the actual underlying table. So what this is actually going to do is run SQL that looks like
select * from posts
inner join taggings on taggings.post_id = posts.id
inner join tags on taggings.tag_id = tag.id
where tags.name = 'foo';
Since we've declared how the tables are related in the models, rails knows what it has to join together to query tags with the above code.
来源:https://stackoverflow.com/questions/33108372/rails-query-by-record-association