Hi all,
My apologies, but I am just starting with Rails. I'm curious as to why there is no "belongs_to_many" as opposed to the current need to contruct a relationship that basically means the same thing with more steps.
Any ideas?
Regards, Mike.
Hi all,
My apologies, but I am just starting with Rails. I'm curious as to why there is no "belongs_to_many" as opposed to the current need to contruct a relationship that basically means the same thing with more steps.
Any ideas?
Regards, Mike.
Hi --
Hi all,
My apologies, but I am just starting with Rails. I'm curious as to why there is no "belongs_to_many" as opposed to the current need to contruct a relationship that basically means the same thing with more steps.
If you have an X that belongs to a Y, that means you'll have a y_id field in the xs (plural of x) table.
If the X belongs to more than one Y, you have to have multiple y_id fields for each record. Since the xs table can only have one y_id column, you have to put the multiple y_ids in a separate table. Each row in that table also gets the corresponding id key from the xes table.
David
Check out this diagram:
http://mboffin.com/stuff/ruby-on-rails-data-relationships.png
It might make the relatioships a bit clearer.
--Dylan
Hi --
Hi Ashley,
Ashley Thomas wrote:
has_one|many creates methods based on the assumption that the other model has a field referencing this model, and belongs_to creates methods based on the assumption that this model has a field referencing the other model. So a belongs_to_many macro would create methods based on the assumption that this model has (infinitely) many fields referencing the other model -- which is more easily implemented with a join table, thus habtm or has_many :through.
Nice explanation.
Best regards, Bill
I understand, but what if I don't necessarily want "both ways"? For instance, in the Oreilly book "Ruby on Rails: Up and Running" they have the example of a Slideshow. The Slideshow has_many Slides, and Photos has_many Slides, but Slides belongs_to both Slideshow and Photos. Despite how the items are defined, in English this doesn't seem correct. It seems more likely that, if nothing else, Photos "belongs_to_many" Slides, more than Photos "has_many" Slides, like so:
Slideshow has_many Slides Slide has_one Photo Slide belongs_to Slideshow Photo belongs_to_many Slides
I don't see any need for HABTM, simply, BTM. What am I missing?
Thanks, Mike
Daniel Waite wrote:
Hi --
Daniel Waite wrote:
gberz3 wrote:
I'm curious as to why there is no "belongs_to_many" as opposed to the current need to contruct a relationship that basically means the same thing with more steps.
There is. It's called has_and_belongs_to_many.
Besides that, "belonging to many" is merely the flip side of having many. You can't truly belong to many without also having many.
Have implies a direct ownership, and belongs implies being owned. HABTM goes both directions.
I understand, but what if I don't necessarily want "both ways"? For instance, in the Oreilly book "Ruby on Rails: Up and Running" they have the example of a Slideshow. The Slideshow has_many Slides, and Photos has_many Slides, but Slides belongs_to both Slideshow and Photos. Despite how the items are defined, in English this doesn't seem correct. It seems more likely that, if nothing else, Photos "belongs_to_many" Slides, more than Photos "has_many" Slides, like so:
Slideshow has_many Slides Slide has_one Photo Slide belongs_to Slideshow Photo belongs_to_many Slides
I don't see any need for HABTM, simply, BTM. What am I missing?
I'm not sure I follow. It looks like it's just one-to-many, not many-to-many, so it's not a real test of whether habtm might be useful.
Remember too that the "have/belong" wording is really for the purpose of establishing object-relational mappings, not fully documenting the application. The available relations -- has_one, has_many, etc. -- will never accurately describe what's going on in every domain. You'd really want to say:
class Slide < AR::Base has_been_made_from :photo
or something like that, but we can't The have/belong thing is a
simple mechanism that really just bootstraps a more semantically rich
one.
I also don't see a way to implement belongs_to_many, in database terms consistent with ActiveRecord's logic. Where would you put the foreign keys?
David
Basically, I'd say this:
class Photo < AR::Base belongs_to_many :slides end
. . .and perhaps the following if AR couldn't figure it out
class Slide < AR::Base has_one :photo end
. . .and AR should know to put the FK into Slides. Does that make sense?
Mike
dblack@wobblini.net wrote:
sorry to reopen this but it is a valid issue that has not been taken care of. Also, you guys simple don't get it. From the back end point of view belongs_to_many/has_one is identical to has_many/belongs_to------its the semantics that are different, and simple saying that has_many sets certain things totally skips the meaning of the words. in the from the data side belongs_to_many-has_one==has_many-belongs_to but the switch in syntax and semantics is key, for beauty, understandability, and overall pleasantness. this relationship has many, many cases and its very ugly to be forced to put it backwards.
adding belongs_to_many/has_one is in the core the same as has_many/belongs, (the key will be in the has_one) and there is nothing hard about it
this semantic change is cimple yet greatly usefull and intuitive, and besides ignorance to its simplicity there is no reason why it shouldnt be included soon into ActiveRecord
has_and_belongs_to_many. Use it.
Ryan Bigg wrote:
has_and_belongs_to_many. Use it.
but then an unnecessary intermediary table is created
Ryan Bigg wrote:
has_and_belongs_to_many. Use it.
but then an unnecessary intermediary table is created
So you don't want a join table, in which case there is only one place
the foreign key can sit.
Taking your example from your other thread, the foreign key has to sit
on the os table, which in the rails world means
that os belongs_to hardware.
If I understand you correctly what you want from the point of view of
functionality is hardware has_many oses, and os belongs_to hardware,
but you prefer to think of it as hardware belongs_to_many oses
You could just alias has_many to belongs_to_many if it will help you
out.
Fred
When I read "Also, you guys simple don't get it." I had to chime in here at the irony.
Don't confuse Rails' use of English for handy distinctions between has_many and belongs_to with Rails enforcing real-world distinction between them. They are essentially the same association with the primary distinction being which model/table holds the primary key. There is absolutely no need to create another variant of this association just to please what seems to be a desire for Ruby to match English one-to-one. And if you _must_, alias_method is just a few keystrokes away.
RSL
Hi --
David A. Black wrote:
Hi --
Ryan Bigg wrote:
has_and_belongs_to_many. Use it.
but then an unnecessary intermediary table is created
I don't seem to have received your original post, but the basic answer is: since belonging to is expressed by a foreign key column, if you belong to many, you'd need multiple columns called thing_id (or whatever) in your table, and that's impossible.
David
--
but you can store the key in the has_one table's columns
it makes it so that in your forms and refrences you dont have to put a 'prefix' on everything in a form to add one small thing that happens to have this relationship
It's a design decision and it has been made the naming convention. Where's the problem?
If you want to, go ahead and implement belongs_to_many.
Stefan Buhr wrote:
It's a design decision and it has been made the naming convention. Where's the problem?
If you want to, go ahead and implement belongs_to_many.
I just don't know that much ruby to do it right. But t seems like not to hard to implement by someone who know how to---however it has to be 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).
Fred
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).Fred
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.
Then just alias the methods as I showed.
Fred
Hi --
Stefan Buhr wrote:
It's a design decision and it has been made the naming convention. Where's the problem?
If you want to, go ahead and implement belongs_to_many.
I just don't know that much ruby to do it right. But t seems like not to hard to implement by someone who know how to---however it has to be 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.
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