Вопрос

На этот вопрос уже есть ответ здесь:

Я пытаюсь понять has_one отношения в РоР.

Допустим, у меня есть две модели — Person и Cell:

class Person < ActiveRecord::Base
  has_one :cell
end

class Cell < ActiveRecord::Base
  belongs_to :person
end

Могу ли я просто использовать has_one :person вместо belongs_to :person в Cell модель?

Разве это не то же самое?

Это было полезно?

Решение

Нет, они не взаимозаменяемы, и есть некоторые реальные различия.

belongs_to означает, что внешний ключ находится в таблице для этого класса.Так belongs_to может ТОЛЬКО войти в класс, содержащий внешний ключ.

has_one означает, что в другой таблице есть внешний ключ, ссылающийся на этот класс.Так has_one может ТОЛЬКО войти в класс, на который ссылается столбец в другой таблице.

Итак, это неправильно:

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

И это тоже неправильно:

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

Правильный путь (если Cell содержит person_id поле):

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

Для двусторонней ассоциации вам понадобится по одному каждому из них, и они должны относиться к правильному классу.Даже для односторонней ассоциации имеет значение, какой из них вы используете.

Другие советы

Если вы добавите «belongs_to», вы получите двунаправленную ассоциацию.Это значит, что можно получить человека из клетки и клетку из человека.

Реальной разницы нет, оба подхода (с «belongs_to» и без него) используют одну и ту же схему базы данных (поле person_id в таблице базы данных ячеек).

Обобщить:Не добавляйте «belongs_to», если вам не нужны двунаправленные ассоциации между моделями.

Использование обоих позволяет получать информацию как из моделей Person, так и из моделей Cell.

@cell.person.whatever_info and @person.cell.whatever_info.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top