yes, i tried to say that above: belongs_to_many/has_one is a synonym
for
has_many/belongs_to and is only syntattically differnt, the has_one
oculd be called has_helper or has_utility (thats the items that fit
into
this relationship) to fix that problem.
a special case as such. Do you guys understand how it works? Its
implementation would be quite useful, its ugly to use a refrence table
thats completely unnecciary.
The has/belongs semantics are, indeed, not always a perfect fit for
the way things relate when we describe them in English. For example, I
remember coming up with an example once where I ended up with a Club
belonging to a Member (or something like that; I’m not remembering
exactly), whereas normally we’d say “He belongs to that club.”
My advice would be to use it as is for a while. If you want two-way
has_many’s, then just use has_many. Remember that the main point of
associations, in any case, is that they generate methods for you. It’s
nice to have them as close as possible to the domain you’re modeling,
but it’s often not very close since “has” and “belongs to” are not
general terms for expressing every possible connection between two
things.
In the end, I think it’s better to keep the number of association
methods down, partly because it helps when it comes to learning how
the associations themselves behave – which ones trigger automatic
saves, and when, and things like that.
David
–
Rails training from David A. Black and Ruby Power and Light:
Advancing With Rails August 18-21 Edison, NJ
Co-taught by D.A. Black and Erik Kastner
See http://www.rubypal.com for details and updates!
imamented, and only work as a pair belongs_to_many with has_one, and
as
a special case as such. Do you guys understand how it works? Its
implementation would be quite useful, its ugly to use a refrence table
thats completely unnecciary.
Well as other people have said, you could just alias has_many to
belongs_to_many and has_one
class ActiveRecord::Base
class << self
alias_method :belongs_to_many, :has_many
end
end
Your belongs to many cannot work with the existing has_one: with your
belongs_to_many the foreign key has to exist on the other table, and
with has_one the foreign key also has to work on the associated table.
When you’ve got a pair of relations, one of them has to be a
belongs_to and the other one a has_many/has_one (even if you call them
something else).
class Member < ActiveRecord::Base
This can me implemented the same way as has_and_belongs_to_many, except
that in the joint table the Foreign Key for Members must be required to
be unique.
An Address can be then automatically deleted when the last Member living
at that address is deleted.
The advantage over [belongs_to, has_many] is the same as for has_one
over belongs_to: the Members table does not need to “know” about the
Addresses table.
The thing is, this would just duplicate existing associations; I don’t
see
how it’s needed. The relationship you describe above can be written much
simpler (no join table at all) by just having User belongs_to :address,
and
Address has_many :users.
If it’s the readability of the code that you want, you can always do
things
like
I have just read in RailsGuides ( Active Record Associations — Ruby on Rails Guides )
about the proper way to choose between belongs_to and has_one.
From this point of view, something like belongs_to_many seems to be
really missing, but i do not know if maybe there is a better name, and
how to call the other side of the association (has_a ?).
I am talking about something like this:
class Member < ActiveRecord::Base
has_an :address
end
class Address < ActiveRecord::Base
belongs_to_many :members
end
Different members can have the same address, if they are a couple for
example.
This can me implemented the same way as has_and_belongs_to_many, except
that in the joint table the Foreign Key for Addresses must be required
to be unique (or set as the Primary Key).
An Address can be then automatically deleted when the last Member living
at that address is deleted, and Members should not be deleted if an old
Address is deleted.
The advantage over [belongs_to, has_many] is the same as for has_one
over belongs_to: the Members table does not need to “know” about the
Addresses table.
The has/belongs semantics are, indeed, not always a perfect fit for
the way things relate when we describe them in English. For example, I
remember coming up with an example once where I ended up with a Club
belonging to a Member (or something like that; I’m not remembering
exactly), whereas normally we’d say “He belongs to that club.”
My advice would be to use it as is for a while. If you want two-way
has_many’s, then just use has_many. Remember that the main point of
associations, in any case, is that they generate methods for you. It’s
nice to have them as close as possible to the domain you’re modeling,
but it’s often not very close since “has” and “belongs to” are not
general terms for expressing every possible connection between two
things.
In the end, I think it’s better to keep the number of association
methods down, partly because it helps when it comes to learning how
the associations themselves behave – which ones trigger automatic
saves, and when, and things like that.
David
I am very grateful for this response. I, too was having a bit of
difficulty earlier when the “English just wasn’t making sense”. See, I
have an Event model and a DressCode model and I want to say that Event
has_one DressCode, but I put the foreign key (dress_code_id) in the
Event model (just as I would in my usual SQL/PHP ways. It turned out
that I had to say DressCode has_many Events and Event belongs_to
DressCode. Unorthodox but it works because now I can run
Event.dress_code and I get the result i’m looking for.
Rails is so advanced that I sometimes forget that it is still just a
programming language and, as you said, can’t always be semantically
correct all the time when illustrating real world relationships.
I spent a while searching, ended up on this thread and I finally got my
head around it. To the original poster - just take the advice and do
what needs to be done in order to satisfy the rails convention. Reading
your code might be weird, but that’s nothing that a few comments can’t
fix