(ActiveRecord) Why is there no "belongs_to_many"?

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.

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. :slight_smile:

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.

Check out this diagram:

http://mboffin.com/stuff/ruby-on-rails-data-relationships.png

It might make the relatioships a bit clearer.

–Dylan

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.

Hi –

On Wed, 11 Oct 2006, Daniel W. wrote:

many. You can’t truly belong to many without also having many.
They’re not symmetrical, though: an object can have_many even if each
of the “havees” doesn’t belong to many.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

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

Hi Ashley,

Ashley T. 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

Hi –

On Wed, 11 Oct 2006, gberz3 wrote:

Besides that, “belonging to many” is merely the flip side of having
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 :slight_smile: 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


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Hi –

On Wed, 11 Oct 2006, gberz3 wrote:

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


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

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.

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

Ryan B. wrote:

has_and_belongs_to_many. Use it.

but then an unnecessary intermediary table is created

On 5 Aug 2008, at 12:25, Shawn … wrote:

Ryan B. 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

Hi –

On Tue, 5 Aug 2008, Shawn … wrote:

Ryan B. 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


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!

David A. Black wrote:

Hi –

On Tue, 5 Aug 2008, Shawn … wrote:

Ryan B. 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 B. 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.

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

On Tue, Aug 5, 2008 at 7:31 AM, Frederick C.

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.