Search code examples
ruby-on-railsactiverecordacts-as-taggable

find all children of an object tagged with acts_as_taggable_on


I have a rails site with two models: events and dates

events has many dates

events are tagged using acts_as_taggable_on

I'm trying to find all dates (chronological order) for events tagged with a specific tag. I can figure out how to get all the tagged events, but I can't figure out how to get all of the dates.

The end result I'm looking for is to create a calendar of similar events where events appear on each of their dates.

Hopefully that makes sense, thanks for any and all input!


Solution

  • As you know Events.tagged_with("my_tag") returns a list of events matching your tags.

    You can then use the map or collect operator on this list to get a list of dates for each event.

    `map{|e| e.dates}`
    

    This returns a list of date arrays, where each array the list of dates associated with the event in that index of the list returned by Events.tagged_with("my_tag")

    To order by date you need to flatten and sort.

    flatten.sort{|a,b| a.created_at <=> b.created_at}
    

    Making the entire method call:

    Events.tagged_with("my_tag").map{|e| e.dates}.flatten.sort{|a,b| a.created_at <=> b.created_at}
    

    You can simplify this with a named scope on dates. It will be a faster query, but I can't write one for you without knowing more about the structure of your database.

    It would look something like this, assuming dates belong to an event:

    class Date < ActiveRecord::Base
      ...
      named_scope :for_tag, lambda do |tag|
        {:joins => [:tags, :taggings], 
         :conditions => ["tags.name = ? AND tags.id = taggings.tag_id \
           AND taggings.taggable_id = dates.event_id AND \
           taggings.taggable_type = event", tag],
         :order => 'dates.created_at'}
      end  
    end
    

    You could then do Date.for_tag("my_tag") and retrieve the same list, in a much more efficient SQL query.