Разница между has_one и own_to в Rails?

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

Допустим, у меня есть две модели - 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 модель?

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

3 ответа

Решение

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

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

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

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

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

Подводя итог: не добавляйте "assign_to", если вам не нужны двунаправленные связи между моделями.

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

@cell.person.whatever_info and @person.cell.whatever_info.
Другие вопросы по тегам