-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Thushan wrote:> Why do we need to specify both sides of a relationship?
> eg.
> class Category < ActiveRecord::Base
> has_many :recipes
> end
>
> class Recipe < ActiveRecord::Base
> belongs_to :category
> end
>
> Doesn''t "has_many :recipes" in Category imply
"belongs_to :category" in
> Recipe?
>
> I am sure there is a good explanation, but at the moment it looks like
> not(DRY) to me.
>
Ruby reads it source files once and evaluates the code as it goes, you
need both calls so you can let each model know how it''s relationship to
another model.
has_many/belongs_to are simply class methods called on each model class.
They are responsible for defining the relationship of one model to
another. Part of this responsibility entails that they generate instance
methods for the relationship. This is how Category#recipes and
Recipe#category methods exist.
If you remove one of these calls then you are relying on the order in
which model files are read to be able to define the relationship and add
additional methods to the other model class.
ie:
class Category < ActiveRecord::Base
has_many :recipes
end
class Recipe < ActiveRecord::Base
What do you expect to happen in the above? At the time of the call to
"has_many" Recipe doesn''t exist, so you can''t let
Recipe know about it''s
relationship to Category. Now you could change how ActiveRecord works so
Recipe would query a "Association" object to pull in any relationships
it needs to when it is defined as a subclass from ActiveRecord, but then
you have to have two ways to define association related behavior.
Imagine if the classes were loaded in the below order:
ie:
class Category < ActiveRecord::Base
has_many :recipes
end
class Recipe < ActiveRecord::Base
class Group < ActiveRecord::Base
has_many :recipes
end
By the time Group''s relationship is defined to Recipe, Recipe has
already been defined, so Group has to directly modify Recipe itself to
add the relationship information. Not a good idea IMO.
Now, you could do everything dynamically, so that the methods
"categories" and "recipe" are handled via method_missing,
and then each
object looks up relationships (associations) via a
AssociationReflection.lookup, but that is not a very good solution IMO
either because you''d be having models relying on class methods of
another object to do their job. I think it is better to store this
information on the model itself, and let the model take care of it''s
relationships, as it does now with the "reflections" method.
Lastly, has_many/belongs_to are clear in their behavior. You can look at
Category and Recipe and know what relationship they have to other
models. If you remove one-side of this then you lose this. IMO that is a
big loss.
Zach
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFFZw7TMyx0fW1d8G0RAul8AJ41cfFH9OaF+uz/nKB7q3DfieedYQCeNTTY
SZ/fwbH6etGgssWT+dyiFo8=jTpT
-----END PGP SIGNATURE-----
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---