views:

299

answers:

1

Hi

Say I have a model Taggable has_many tags, how may I find all taggables by their associated tag's taggable_id field?

Taggable.find(:all, :joins => :tags, :conditions => {:tags => {:taggable_id => [1,2,3]}})

results in this:

SELECT `taggables`.* FROM `taggables` INNER JOIN `tags` ON tags.taggable_id = taggables.id WHERE (`tag`.`taggable_id` IN (1,2,3))

The syntax is incredible but does not fit my needs in that the resulting sql returns any taggable that has any, some or all of the tags.

How can I find taggables with related tags of field taggable_id valued 1, 2 and 3?

Thanks for any advice. :)

UPDATE:

I have found a solution which I'll post for others, should they end up here. Also though for the attention of others whose suggestions for improvement I'd happily receive. :)

Taggable.find(:all, :joins => :tags, :select => "taggables.*, tags.count tag_count", :conditions => {:tags => {:taggable_id => array_of_tag_ids}}, :group => "taggables.id having tag_count = #{array_of_tag_ids.count}"))
A: 

Your question is a bit confusing ('tags' seemed to be used quite a bit :)), but I think you want the same thing I needed here:

Taggable.find([1,2,3], :include => :tags).tags.map { |t| t.taggables }

or (if you want the results to be unique, which you probably do):

Taggable.find([1,2,3], :include => :tags).tags.map { |t| t.taggables }.flatten.uniq

This gets at all the taggables that have the same tags as the taggables that have ids 1,2, and 3. Is that what you wanted?

aronchick
Hi and thanks for your reply. Sorry for poor explanation, I thought the scenario would be more familiar than what I'm actually working with. I'm afraid I'm not looking to find by taggables by their id but taggable's by their associated tag's taggable_id. This kind of thing would be done in mysql with group by but would prefer not to have to write mysql into my app.
mark
Sorry, still not entirely clear. So you have a join table in your DB that is between Tag and Taggable? Can you just write the SQL and I'll try to translate into Ruby for you.
aronchick