find all children of an object tagged with acts_as

2019-04-15 18:52发布

问题:

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!

回答1:

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.