views:

37

answers:

1

My situation is like this. Company has many users and users may belongs to many companies. And current implementation is something like below.


  class Company 
    has_many :employments
    has_many :users, :through => :employments
  end

  class Employment 
    belongs_to :company
    belongs_to :user
  end

  class User
    has_many :employments
    has_many :companies, :through => :employments  #This doesn't looks correct
  end

It works, but "user has many companies" doesn't looks logically meaningful. It must be some thing like belongs_to_many companies. Do I need to use has_and_belongs_to_many?

Can some one please suggest the right way for representing these relationships?

A: 

If you are not going to add some special behaviour to Employment class and you don't really need it, then you should propably better use has_and_belongs_to_many. This way it will still have some table called CompanyUser, but there will not be any such class in the code.

Added: There are just 3 possbile conections between 2 objects: 1-to-1, 1-to-many and many-to-many. Rails indicates with has_* or belongs_to what of the 2 objects will get a foreign key. So:

  • 1-to-1:

    has_one and belongs_to are used. The object with belongs_to gets the FK.

  • 1-to-many:

    has_many and belongs_to are used. The object with belongs_to gets the FK.

  • many-to-many:

    has_many[through] or has_and_belongs_to_many are used in both objects. No-one gets a FK, instead a ConnectionTable is used.

So there is no such thing as belongs_to_many, because it would be the same as has_many - providing the same relation 1-to-many.

Draco Ater
I feel, has_and_belongs_to_many also gives the same meaning. "User has and belongs to many companies."Another similar type of relationship, probably best explains my doubt.String has many characters and character belongs to many strings.If we write Character has and belongs to many strings, that has part doesn't looks correct. Probably I should not take the literal meaning.
Vijendra
I added some more info to the answer.
Draco Ater