Question

Say you have a posts table and a tags table, and both are related by a post_tags table.

so

posts has id/subject/body columns

tags has id/name

post_tags has id/post_id/tag_id

in rails terminology, I have a Post Model that has many Tags through AssetTags.

I'm trying to query for a post that has 2 specific tags. so if there is a rails tag and a mysql tag, I want a query that returns a post that only has those two tags.

make sense?

Any way to do this with activerecord (I'm using search logic) or mysql?

Was it helpful?

Solution

This SQL returns the posts that contain both tags.

select 
  p.* 
from 
  posts p
  ,asset_tags atg1
  ,asset_tags atg2
  ,tags t1
  ,tags t2
where
  p.id = atg1.post_id
and t1.id = atg1.tag_id
and t1.tag = 'MySQL' 
and p.id = atg2.post_id
and t2.id = atg2.tag_id
and t2.tag = 'Rails'
;

As for doing it via Active record, an alternative would be to query for each of the tags and then & the resulting arrays to get the intersection of the two.

OTHER TIPS

For mysql, sure, you can get the data

 SELECT p.*
   FROM posts p 
   JOIN post_tags pt
     ON p.post_id = pt.post_id
  WHERE pt.tag_id in (tagId1, tagId2)

I have not used Rails ActiveRecord but I imagine it would be something along the lines of

 get('posts');
 join('post_tags','post_id');
 where_in('tag_id', array(tagId1, tagId2);
 execute();

Given these models:

def Post
  has_many :asset_tags
  has_many :tags, :through => :asset_tags
end

def AssetTag
  has_one :post
  has_one :tag
end

def Tag
  has_many :asset_tags
  has_many :posts, :through => :asset_tags
end

You can do this:

Post.joins(:asset_tags => :tag).where(
  "tags.name in ('?', '?')", 'foo', 'bar' )

Now, this actually doesn't do anything with the has_many :through association -- I'm not sure if there's an even slicker api provided that utilizes that.

John Bachir's answer can be modified to...

Post.joins(:asset_tags => :tag)
    .where("tags.name in ('?')", 'foo')
    .where("tags.name in ('?')", 'bar')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top