ActiveRecord associations and scopes oh my
-
13-07-2021 - |
Question
I'm trying to figure out how to pull data from multiple tables and making sense of it.
I have events
, occurrences
and venues
tables.
Here are the models/associations so far:
models/event.rb:
class Event < ActiveRecord::Base
has_many :occurences, :dependent => :destroy
belongs_to :price
belongs_to :venue
validates_presence_of :venue
end
models/venue.rb:
class Venue < ActiveRecord::Base
has_many :events, :dependent => :destroy
end
models/occurence.rb:
class Occurence < ActiveRecord::Base
belongs_to :event
scope :today, lambda { where("occurence.datetime_start <= ? AND datetime_end >= ?", Time.now.end_of_day, Time.now) }
scope :this_week, lambda { where("occurence.datetime_start <= ? AND datetime_end <= ?", Time.now.end_of_day, Time.now.at_end_of_week) }
scope :next_week, lambda { where("occurence.datetime_start > ? AND datetime_end < ?", Time.now.at_end_of_week, Time.now.at_end_of_week + 1.weeks) }
scope :this_month, lambda { where("occurence.datetime_start <= ? AND datetime_end >= ?", Time.now.end_of_day, Time.now.at_end_of_month) }
scope :next_month, lambda { where("occurence.datetime_start >= ? AND datetime_end <= ?", Time.now.at_beginning_of_month + 1.months, Time.now.at_end_of_month + 1.months) }
end
What I'd like to show in my view/events/index.html.erb is a table of all events happening today and I like to do something like:
<% @events.today.each do |event| %>
and display all the events that match the .today
scope.
I tried moving the scope to the event
model to no avail. Should I move the scopes to the event model? So far my searches have lead me to
"Using scope to return results within multiple DateTime ranges in ActiveRecord"
and
"Multiple scope in rails 3.0" but I can't really make anything out of it.
Can anyone point me in the right direction? Should I create a new function in my event model?
Solution
class Event < ActiveRecord::Base
has_many :occurences, :dependent => :destroy
belongs_to :price
belongs_to :venue
validates_presence_of :venue
scope :today, lambda {
joins(:occurences).where("datetime_start <= ? AND datetime_end >= ?", Time.now.end_of_day, Time.now)
}
end
OTHER TIPS
If you want your syntax to work like:
@events.today
Then the scope would have to be in the Event
model.
If you're OK with:
@event.occurences.today
then you're OK now, i.e.:
@events = Event.all
@events.each do |ev|
ev.occurences.today.each do |oc|
end
end