views:

20

answers:

1

I've been applying has and belongs to many style associations to a project I've been working on, but because I wanted to capture extra information in my join model, I'm implicitly setting it up via the more elaborate belongs_to/has_many approach instead of has_and_belongs_to_many. After initially stumbling on this, I learned that I needed both of these definitions in my model User (and the same in the Show model counterpart):

has_many :saved_shows
has_many :shows, :through :saved_shows

Everything works, and my question is more about the design of the Rails syntax, because I want to make sure I'm not missing the bigger picture here: why is the first one necessary? If we're establishing that a user can access a list of shows through an intermediate with a non standard name of saved_shows, why also establish has_many :saved_shows?

I'm guessing I'm not the first one to have hit a snag on this one, so I'm curious why Rails requires this seemingly redundant definition. Is it just a poorly chosen syntax or is there some deeper design behind it?

+1  A: 

Rails uses the :through option to reference another association you have already defined. I think it does this so that you can cleanly set up complex associations first, without defining them and referencing them in the same line.

For example, consider this (needlessly complex) example:

has_many :users, :class_name => 'Person', :foreign_key => 'owner_id'
has_many :tasks, :through => :users, :class_name 'Job'

There's no clean way to express all this information inline.

In addition (not sure if you're implying this in your question), you can explicitly access both associations directly. So if a user has_many :tasks, and has_many :milestones, :through => :tasks, you can and will want to access both @user.tasks and @user.milestones.

So it's not only useful for going through what's more or less a join table in your example (two foreign keys, timestamps, and maybe an attribute or two) - you can have large models that you use a has_many :through on.

Does that help answer your question? Not sure how much of that you already know.

nfm
That makes a lot of sense now. I hadn't considered more complex scenarios yet like your example brings up, because my early app hasn't needed them yet.
Joost Schuur