has_many/belongs_to and DRY

Can someone tell me whether the fact that ActiveRecord requires both has_many and belongs_to

  * isn't really a violation of DRY

  * is a necessary violation of DRY

  * is an unnecessary violation of DRY, which (will/won't)      go away in time, for the following reason...

That is, does using both statements tell ActiveRecord something that it couldn't figure out from either one?

-r

belongs_to is a to-one relation, has_many is a to-many relation, so they are obviously different. If you meant belongs_to and has_one, then the difference is the location of the foreign key - the model with belongs_to will contain a foreign key for the relation, the model with has_one won't.

Paul

belongs_to is a to-one relation, has_many is a to-many relation, so they are obviously different.

Sorry, wasn't being careful.

If you meant belongs_to and has_one, then the difference is the location of the foreign key - the model with belongs_to will contain a foreign key for the relation, the model with has_one won't.

OK, I understand that, but why (aside documentation and/or implementation details) does the relationship have to be expressed in both models? That is, does "belongs_to B" in A imply "has_one A" in B?

-r

Can someone tell me whether the fact that ActiveRecord requires both has_many and belongs_to

  * isn't really a violation of DRY

  * is a necessary violation of DRY

  * is an unnecessary violation of DRY, which (will/won't)      go away in time, for the following reason...

That is, does using both statements tell ActiveRecord something that it couldn't figure out from either one?      belongs_to is a to-one relation, has_many is a to-many relation, so they are obviously different. If you meant belongs_to and has_one, then the difference is the location of the foreign key - the model with belongs_to will contain a foreign key for the relation, the model with has_one won't.   

i think what he means is that if a model A has a has_many B, then model B will always belong_to model A, and this doesn't need to be redefined. On the other hand if model B belongs_to model A then model A doesn't necessarily has_many B

Dr Nic's Magic Models would answer your question, then you don't need to define any of it.

No, and you might choose to model a one-way relationship for performance (or other) reasons. This concept isn't application to a relational database, but is very significant to an OO language implementation like ActiveRecord. The example I usually give is of a customer database with a country table - often most customers will be in one country, with many thousands. It makes sense to model the relation from customer to country, but the inverse relationship has little value, slows down new customer insertions, and can be faked out with a find, anyway, if you really need it.

So, yes, I find the separation necessary.

Paul

Rich Morin wrote:

OK, I understand that, but why (aside documentation and/or implementation details) does the relationship have to be expressed in both models? That is, does "belongs_to B" in A imply "has_one A" in B?

Its all to do with implementation details (which I know you said "aside from implementation details"), not of the associations, but of dynamic model loading.

The model classes aren't loaded into memory when your rails app is launched, instead they are loaded when you first ask for them (Dr Nic's Magic Models extends this idea by creating the model class even if it doesn't exist in your application).

So, if you had Person and Membership classes, where Person.has_many :memberships; and Membership.belongs_to :person; it is theoretically possible for the Person.has_many class method to invoke Membership.belongs_to :person automatically for you.

But, what if you access the Membership class first? Due to the dynamic loading, if the Person class hadn't been loaded yet, it wouldn't have generated the has_many and belongs_to associations for us. Our Membership class would be ignorant of its relationships with other classes.

Inner Rails workings are fun, eh? :slight_smile:

Cheers Nic

OK, I understand that, but why (aside documentation and/or implementation details) does the relationship have to be expressed in both models? That is, does "belongs_to B" in A imply "has_one A" in B?

Just down to implementing the the methods that are added to each class because of their end of the relationship. I find it elegant to know within the model I am editing what it's end of the relationship is and with whom so it is just that bit kinder to the developer.