Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I query for an Activity that has 3 tags?

I have the following models:

activity.rb

tag.rb

tagging.rb

Tagging is a join model for activity and tag.

I would like to search an Activity that has 2 or more tags. How do I do this in rails?

For example:

I have tag1 = Christmas, tag2 = Florida, tag3 = John

I want to find the Activity where tag1, tag2 and tag3 are present if it exists.

[EDIT]

What I ended up doing:

tags = [tag1, tag2, tag3]

activities = []
tags.each do |tag|
  activities << tag.activities
end

activities.flatten.group_by { |activity| activity.id }

If any of the groups values' size is equal to tags.size then that activity contains all tags.

like image 484
Marius Pop Avatar asked Oct 27 '12 01:10

Marius Pop


2 Answers

If you want to have those activities where a particular tags should exist then try out teh following command

selected_activity = Activity.all.select do |activity|
                      %w(Christmas Florida John).all? do |name|
                        activity.tags.include?(name)
                      end 
                    end

Once it runs we can always refactor it so as to reduce the number of queries which are fired...

like image 70
Aditya Kapoor Avatar answered Oct 11 '22 15:10

Aditya Kapoor


Not sure but this should be a better performant way to achieve it. But there should be an even better way

tags_ids = [tag1, tag2, tag3].map(&:id)
ativities_ids = Tagging.where(tag_id: tags_ids).group("activity_id having count(tag_id) = #{tags_ids.size}").select('activity_id').map(&:activity_id)
Activity.find(activities_id)

This will get activities that have those tags, but they can have others too.

like image 25
Ismael Avatar answered Oct 11 '22 13:10

Ismael