views:

6859

answers:

4

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|
  results << 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)?

Thanks so much!

+12  A: 

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
Beautiful, that'll do great.
Stefan Mai
I've marked you up, but if I don't get a better answer by morning it's yours.
Stefan Mai
okay. I'm in Europe, so I'll wait till the sunset ;)
Milan Novota
+1  A: 

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

Gareth
I like to define all the scopes at one place - in the model, even if I use them just once. It keeps my controllers thin and the overall design more consistent.
Milan Novota
Definitely good to know, thanks Gareth.
Stefan Mai
+1  A: 

You could also create a named scope using Gareth's suggestion.

arjun
A: 

I used Milan's suggestion for a similar model and it works well - as long as I access data as @user and @user.events. But if I try to use :include so the events are eagerly loaded, I get error messages about my condition column not being in the event table. It isn't, it is in the join table. This is an already launched app running Rails 2.1.2. Is this fixed in 2.3.2?

cnk