Landitus
Landitus

Reputation: 1900

Rails 3: filter from assosiated records returned by has_many

I'm trying to explain something quite complex. Perhaps more complex to say than do. I have "events". These events belong to "venues". So venues have_many events in the venues model.

But events are complicated and have scopes to determine if the event is past, present or future. The scope which gets the correct events (future or present only) is:

scope :not_over_or_in_progress, lambda { where("start_date < ? AND end_date > ? OR end_date IS NULL AND start_date > ? OR end_date IS NOT NULL AND start_date > ? OR start_date = ? OR end_date = ?", Date.today,  Date.today, Date.today, Date.today,  Date.today,  Date.today) }

scope :valid, (not_over_or_in_progress.active).order("start_date ASC")

Not very pretty but works ok. Now when I show a venue, I can get the associated events with:

<% @venue.events.each do |event| %>
  <li><%= event.title %> - (<%= event.event_status? %>)</li>
<% end %>

I get all events, whether they are past, present or future. It's not returning @events.valid, but @events.all (all of them). I would like to get the associated events filtered by my scope (valid) of by my helper (event_status?). Is that possible?

I get some helpers I did to determine if the event is over. That's what event_status? is for. Maybe it helps

Upvotes: 0

Views: 431

Answers (1)

thomasfedb
thomasfedb

Reputation: 5983

Your need to change:

<% @venue.events.each do |event| %>
  <li><%= event.title %> - (<%= event.event_status? %>)</li>
<% end %>

into:

<% @venue.events.valid.each do |event| %>
  <li><%= event.title %> - (<%= event.event_status? %>)</li>
<% end %>

You also might like to know that if you use the meta-where gem, then you can change your scope from:

scope :not_over_or_in_progress, lambda { where("start_date < ? AND end_date > ? OR end_date IS NULL AND start_date > ? OR end_date IS NOT NULL AND start_date > ? OR start_date = ? OR end_date = ?", Date.today,  Date.today, Date.today, Date.today,  Date.today,  Date.today) }

into:

scope :not_over, lambda { where(:start_date <= Date.today, :end_data >= Date.today) | where(:start_date = Date.today, :end_date => nil)} 

Put this in an initializer

MetaWhere.operator_overload! 

(much cleaner?)

Upvotes: 1

Related Questions