Difference between has_one and belongs_to in Rails?

Ruby on-RailsRubyHas One

Ruby on-Rails Problem Overview


I am trying to understand has_one relationship in RoR.

Let's say I have two models - Person and Cell:

class Person < ActiveRecord::Base
  has_one :cell
end

class Cell < ActiveRecord::Base
  belongs_to :person
end

Can I just use has_one :person instead of belongs_to :person in Cell model?

Isn't it the same?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

No, they are not interchangable, and there are some real differences.

belongs_to means that the foreign key is in the table for this class. So belongs_to can ONLY go in the class that holds the foreign key.

has_one means that there is a foreign key in another table that references this class. So has_one can ONLY go in a class that is referenced by a column in another table.

So this is wrong:

class Person < ActiveRecord::Base
  has_one :cell # the cell table has a person_id
end

class Cell < ActiveRecord::Base
  has_one :person # the person table has a cell_id
end

And this is also wrong:

class Person < ActiveRecord::Base
  belongs_to :cell # the person table has a cell_id
end

class Cell < ActiveRecord::Base
  belongs_to :person # the cell table has a person_id
end

The correct way is (if Cell contains person_id field):

class Person < ActiveRecord::Base
  has_one :cell # the person table does not have 'joining' info
end

class Cell < ActiveRecord::Base
  belongs_to :person # the cell table has a person_id
end

For a two-way association, you need one of each, and they have to go in the right class. Even for a one-way association, it matters which one you use.

Solution 2 - Ruby on-Rails

If you add "belongs_to" then you got a bidirectional association. That means you can get a person from the cell and a cell from the person.

There's no real difference, both approaches (with and without "belongs_to") use the same database schema (a person_id field in the cells database table).

To summarize: Do not add "belongs_to" unless you need bidirectional associations between models.

Solution 3 - Ruby on-Rails

Using both allows you to get info from both Person and Cell models.

@cell.person.whatever_info and @person.cell.whatever_info.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMoonView Question on Stackoverflow
Solution 1 - Ruby on-RailsSarah MeiView Answer on Stackoverflow
Solution 2 - Ruby on-RailsPablo FernandezView Answer on Stackoverflow
Solution 3 - Ruby on-RailsJarrodView Answer on Stackoverflow