Me
About
Gallery
Company
Girl


Projects
Ruby on Rails
Basecamp
Highrise
Backpack
Campfire
Ta-da List
Writeboard


More
Feed
Archives

May 12, 0:52

A many-to-many relationship

Active Record is doing a lot of magic to simplify associations between objects and their records in the database. Ruby is making this particularly easy due to ability of running methods during class definitions, which makes for instant domain specific languages.

Consider this:


class Project < ActiveRecord::Base
  belongs_to :portfolio
  has_one    :project_manager
  has_many   :milestones
end

Our project objects are now able to respond to methods such as project.portfolio, project.has_project_manager?, and project.create_in_milestones("deadline" => Date.today + 5). This massively simplifies the wiring of the domain model and makes it much easier to traverse the graph when you get hold of just one of the ends.

I'm also particularly fond of the naming scheme, which makes reading aloud a natural task. "Project belongs to Portfolio", "Project has one Project Manager", and "Project has many Milestones". Great.

But how do we represent many-to-many relationships? Currently, it has the slightly clumsy macro of has_and_belongs_to_many, as illustrated below:


class Project < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

This makes it possible to do things like project.add_categories(critical, technical) that'll create relationships with the critical and technical category objects through a join tabel. It's also fairly readable as you'd say "Project has and belongs to many Categories".

But, it's also a little clumsy. So here's a challenge: By which other name may the m-m association macro in Active Record smell as sweet? The rules are pretty simple:

  • It has to read aloud with natural ease
  • It has to follow the form of has_one, has_many, and belongs_to
  • It has to be less clumsy than the current naming

There's an honorable mentioning in the Active Record README at stake to anyone who can crack this (priceless tribute, really!).


Challenge by Micah on May 12, 1:22

The only other name I can think of just cuts out a few characters, "has_and_is_of_many. Would it make sense to change "belongs_to" to "belongs_to_one" and add "belongs_to_many" letting the combination of the two, "belongs_to_many" and "has_many" identify the many to many relationship?

Challenge by David Heinemeier Hansson on May 12, 1:26

This is often an equal relationship, so it doesn't necessarily make sense to think of it as one party belonging to another. Where the other macros has clearly defined parent/child relations, this is more like brother/sister.

Challenge by Xen on May 12, 1:36

The best I could come up with at this hour:

references :categories
uses :categories

Actually, I'd be inclined to use 'xrefs :categories', as that's 'natual language' when I talk with my fellow coders.

Challenge by Luke Holden on May 12, 8:06

Different macro names I can think of... none of which are all that great... or even worth using. Some of which are kindof silly.



has_ties_to

has_many_ties_to

has_mapping_to

has_relations_to

has_bidirectional_many

has_sister
has_peer



never said I was creative =)

Challenge by Thomas on May 12, 15:01

network theory.

has_relations_to

has_links_to

Challenge by David Heinemeier Hansson on May 12, 16:14

While I like the relations/reference notation, they could just as well describe a one-to-one link, which makes them a little too vague.

Challenge by Morten on May 12, 16:23


The relationship is called "many to many" - people know what that is right away, which is important. Unfortunatly, this means that it's hard to get rid of the verbosity in the macro name.

is_many_to_many_related_to
has_many_to_many_relationship_with
is_slutty :-)

Challenge by David Heinemeier Hansson on May 12, 16:27

Well, it's also called "one-to-many" and "one-to-one", but still Active Record chooses to name it "has_many" and "has_one". I like the last suggestion, though ;).

Challenge by Lau Taarnskov on May 12, 17:33

"Project ... has many-to-many relationship with Categories."
becomes: has_many_to_many :categories

Challenge by gabriele on May 13, 7:12

reading fast and running away in one minute.. but could'nt we just express has_and_belongs_to_many as a pair of separated methods ?

Challenge by Rel on May 23, 19:54

module Relation
#mix in as needed
def has_many (...&block) ... end
end

class Project
has_many :categories { inverse :has_many :projects }
end

Gives navigation in both directions, either by storing or searching. Using "inverse" is useful for all other relations too.

Have you considered using a Relation (as in pairings of objects) package, with domain, co-domain, and other relation-like operators? Then allow objects to contain relations between other objects. Each Project instance contains its own relation (set of pairs) between Person and Task.

Challenge by David Heinemeier Hansson on May 23, 20:00

These relations are only used to describe relations between Active Record objects, so the "inverse" idea seems to just be another way of saying "has_many :projects" right in the Category object.

And that was really what I didn't want as it necessitates knowledge of both sides of the relation at the time the macro is handled. It's incredibly much simpler just to parse macros on a per-object basis.

I'm not sure I understand the relation idea? Is it so project can describe relations between person and task that neither person nor task wants to know about? If so, they already kinda does need to know about it as associations in all but the many-t0-many case relies on foreign keys. So I don't know how much it would help.

Challenge by Rel on May 24, 10:44

I think many-many should be declared "as though" at both ends; hence I wrote the version with the "inverse" in the block. You can always handle that block right in the Project class if you need.

Moreover, has_many could do the "inverse" thing on each category Object if needed, without knowledge of the class at the other end.

The relation idea is separate, and applies even if implemented by foreign keys. It solves a particular problem: declaring multiplicity at the class level leaves a whole host of constraints unstated. Declaring it at the object level makes those constraints simple. Google "Constraint Diagrams" by Stuart Kent.

Challenge by Ian on May 26, 2:25

So why isn't splitting it into:

has_many: categories
belongs_to_many: categories

an option? Its clear what its doing without the need for a long line.

Challenge by David Heinemeier Hansson on May 26, 10:31

Because "has_many" uses a foreign key on child classes approach whereas has_and_belongs_to_many uses a join table (and it's the latter we want). Also, it doesn't really work to split it in two since the macro does all the work in one go. Adding the methods needed to the class in question and so on.

Challenge by Xen on May 26, 14:03

Haven't come up with a better name, but I was looking at:

belongs_to :portfolio
has_one :project_manager

What's the difference? And what about might_have_one :project_manager, is that implemented somehow?

Challenge by David Heinemeier Hansson on May 26, 20:07

If you use belongs_to, you hold the foreign key (in the example the class in question will have portfolio_id as a foreign key). If you use has_one, the foreign key sits on the other class. "has_one" also adds a number of extra methods, like build_project_manager, that belongs_to doesn't get.

might_have_one is the same. With "has_one" you get a query method, such as has_project_manager?, to determine whether a relation exists.

Challenge by Michael Leuchtenburg on December 23, 5:16

connects_to_many: lists

Challenge by Piers Cawley on January 06, 21:43

You can do it with multiple helpers by deferring accessor creation 'til (say) the first time you create an ActiveRecord.

Then has_many, belongs_to etc are used to build MethodBuilder method objects associated with each of the symbols. ActiveRecord::new then calls each MethodBuilder in turn the first time it's executed for a given class (or, for bonus points you could track whether a MethodBuilder has been created or changed since the last time new was called and execute any new ones every time).

So, has_many would do something like: 'target_class.attr_cache.method_builder.set_has_many(...)'
if the AccessorBuilder has already been set with 'belongs_to' it would replace itself with a ManyToManyAccessorBuilder

Challenge by corey lawson on February 13, 10:33

Why not just make it work with:

has_many: categories;
belongs_to: categories;

?

The more I think about it, the more Rails' internal language starts to resemble OCL (Object Constraint Language), and that's not a bad thing. Hmm...

Challenge by Andrew on March 13, 12:48

How about:

has_intersection_with

Challenge by Nicholas Wright on March 31, 23:12

relates_to_many
interacts_with_many
maps_to_many

Challenge by Jacob Stetser on May 12, 5:53

Honestly, has_and_belongs_to_many is only clumsy in its length. I think it succinctly states the relationship in a way that most of the other suggested names don't. I can wrap my head around habtm so much more easily than things like crossreferences_with, interacts with many. In addition, the suggested names just don't convey the same information.

I'd just alias habtm to has_and_belongs_to_many and be done with it. That acronym seems to be the most famous of all Rails-isms anyway, so why not make the best of it?

Challenge by Matt Lyon on May 12, 10:41

Couple of other ideas, just to throw out there:

joins_to
joins_to_many
joins_with
joins_with_many
is_siblings_with
is_peers_with
has_peers_with
meshes_with
associates_with

...describing a manymany relationship in english using 'possessive' terminology isn't easy, because, well, that'd be communistic. :)

hmm:

comrades_with

Challenge by Jacob Stetser on May 12, 20:29

don't forget

(joking)
has_orgy_with
is_polyamorous_with

(a little more serious)
has_multiple_relations_with
has_many_relationships_with
corresponds_to_many

These go a little further in describing the same thing as has_and_belongs_to_many... I'm still partial to the original, but my favorite of my suggestions is corresponds_to_many

My favorite of the rest is xrefs, but that's because of its shortness. I don't think using it would follow POLS, though. Again, something like that seems better as an alias for, rather than a replacement of has_and_belongs_to_many

Challenge by Jacob Stetser on May 12, 20:46

Also

correlates_with_many

It's like relates_to_many, but the important part is the 'co' prefix, which implies a two-way relationship. def: (have a mutual relationship or connection, in which one thing affects or depends on another).

Hope I'm not spamming your comments.. Just thought up the new one while playing with Dictionary.app

Challenge by Jacob Stetser on May 25, 10:23

Bah, that's what happens when I don't scrutinize the dateline closely enough... I didn't realize this post was a year old!

Challenge by mary on June 04, 12:12

Hello. I am new here. It is very interesting.
mature bitches free thumbnail pictures of older women mature amature older s3xy women older moms south indian mature women mature bitches nud3 senior women older s3xy women mature gallerys mature bitches nud3 senior women older women and younger men free thumbnail pictures of older women mature amature free naked older women older s3xy women classic mature free naked older women older s3xy women mature living mature nud3 pics mature spunker free naked older women mature bitches nud3 senior women mature gallerys mature bitches mature bitches mature gallerys mature spunker mature ladies in lingerie mature nudists photos nud3 senior women mature living lyrics to older country songs mature amature south indian mature women nud3 senior women mature amature

Challenge by den on June 04, 20:00

Sorry for my links
free anal creampie movies free creampie video hairy creampie creampies movies japanese creampie links creampies movies wife oral creampies japanese creampie links creampie video store creampie ass japanese creampie links creampie video store creampie video clips free creampie thumbnails japanese creampie links cum creampie creampie t9p cum creampie free creampie video creampie ass creampie eating stories creampie t9p free creampie pics free free anal creampie movies xyx creampies creampie video clips japanese creampie links free creampie video creampies free creampie t9p cum creampie creampie video clips ass creampie ass creampie free anal creampie movies free creampie pics free japanese creampie links creampie eating stories creampies free wife oral creampies

Challenge by alan on June 05, 9:32

Sorry for my links
free creampie clips free creampie clips creampie pussies latina creampie creampie pic pictures creampie creampie pussies creampie pussies amature creampies free anal creampie pics creampie movie creampie cum and amature amature creampies creampie cum and amature gangbang creampies videos creampie movie creampies xyx creampies xyx interracial wives bareback creampies free creampie clips free creampie pics free creampie pic free creampie s3x free creampie s3x amature creampies creampies free creampie internal, cumshots free creampie pics and stories creampie cum and amature free creampie clips interracial wives bareback creampies creampie pic latina creampie creampie movie amature creampies creampie p0Rn creampie internal, cumshots gangbang creampies videos creampie anal free creampie clips

Challenge by irgy on June 05, 17:31

Sorry for my links
mature women t9p mature men galleries mature babes mature men galleries mature women nud3 older women younger men older men younger women dating mature women mature women t9p mature women in stockings mature women t9p mature asian free mature s3x free mature p0Rn mature women t9p mature asian free older women mature men galleries mature women nud3 mature asian dating mature women mature asian mature 1esbians mature over 50 mature wives old naked women mature amateur mature wives older thumbs mature wives mature amateur free mature mature women in stockings free mature p0Rn free older women mature nud3 women mature wives mature asian mature babes mature men galleries

Challenge by boris on June 06, 1:15

Sorry for my links
1ncest free pictures stories 1ncest sites granny 1ncest 1ncests mother son 1ncest pics free 1ncest sites 1ncest daughter free 1ncest story 1ncest 101itas free 1ncest sites 1ncest thumbnails 1ncest daughter mom and son 1ncest free family 1ncest stories 1ncest daughter 1ncest sites mother son 1ncest pics 1ncest gallery free 1ncest mpegs 1ncest free pictures stories 1ncest 101ita 1ncest mother son mother son 1ncest pics 1ncest 101itas mom and son 1ncest 1ncest free pictures stories free family 1ncest stories 1ncest daughter mom and son 1ncest 1ncest daughter 1ncests free 1ncest sites mom and son 1ncest 1ncest sites granny 1ncest 1ncest xyx granny 1ncest mother son 1ncest pics free family 1ncest stories 1ncest 101itas

Challenge by abay on June 06, 11:35

Hi. This is my links.
thumbs gallery older women older women stories mature big tits older black women naked old women thumbs older holland mature index mature hardcore links mature big tits thumbs gallery older women black older ladies naked old women thumbs mature glamour young girls older men mature mistress older black women young girls older men mature mistress black older ladies older women stories thumbs gallery older women mature hardcore links thumbs gallery older women how to meet older women mature pic gallery mature pantyhose pictures older holland older black women mature index older 1esbians older 1esbians black older ladies mature pantyhose pictures mature big tits black older ladies mature nudists naked old women thumbs mature big tits mature pic gallery black older ladies

Challenge by lorry on June 08, 0:23

Hi. This is my links.
hooters girls in pantyhose cheerleader panty pics free teen panties mature women in pantyhose white pantyhose cheerleader panty pics pantyhose images mature ladies in pantyhose hooters girls in pantyhose satin panty galleries white pantyhose free teen panties white pantyhose panty post girls in nylons hooters girls in pantyhose satin panty galleries winnie-cooper pantyhose white pantyhose mature women in pantyhose pantyhose images wet pantyhose hooters girls in pantyhose free wet panty mature women in pantyhose panty fetish hooters girls in pantyhose mature ladies in pantyhose pantyhose images celebrities in pantyhose winnie-cooper pantyhose panty fetish mature women in pantyhose men's pantyhose celebrities in pantyhose satin panty galleries girls in nylons mature women in pantyhose winnie-cooper pantyhose celebrities in pantyhose