New to both Ruby and Rails but I'm book educated by now (which apparently means nothing, haha).
I've got two models, Event and User joined through a table EventUser
class User < ActiveRecord::Base
has_many :event_users
has_many :events, :through => :event_users
end
class EventUser < ActiveRecord::Base
belongs_to :event
belongs_to :user
#For clarity's sake, EventUser also has a boolean column "active", among others
end
class Event < ActiveRecord::Base
has_many :event_users
has_many :users, :through => :event_users
end
This project is a calendar, in which I have to keep track of people signing up and scratching their name out for a given event. I figure the many to many is a good approach, but I can't do something like this:
u = User.find :first
active_events = u.events.find_by_active(true)
Because events don't actually HAVE that extra data, the EventUser model does. And while I could do:
u = User.find :first
active_events = []
u.event_users.find_by_active(true).do |eu|
active_events << eu.event
end
This seems to be contrary to "the rails way". Can anyone enlighten me, this has been bugging me for a long time tonight (this morning)?
How about adding something like this into your User model?
has_many :active_events, :through => :event_users,
:class_name => "Event",
:source => :event,
:conditions => ['event_users.active = ?',true]
After that you should be able to get active events for a user just by calling:
User.first.active_events
Milan Novota has a good solution – but :conditions
is now deprecated and the :conditions => ['event_users.active = ?',true]
bit just doesn't seem very rails anyways. I prefer something like this:
has_many :event_users
has_many :active_event_users, -> { where active: true }, class_name: 'EventUser'
has_many :active_events, :through => :active_event_users, class_name: 'Event', :source => :event
After that you should still be able to get active events for a user just by calling:
User.first.active_events
Even though your u.events isn't explicitly calling the user_events table, that table is still included in the SQL implicitly because of the necessary joins. So, you can still use that table in your find conditions:
u.events.find(:all, :conditions => ["user_events.active = ?", true])
Of course, if you plan to be doing this lookup a lot then sure, give it a separate association as Milan Novota suggests, but there's no requirement for you to do it that way
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With