2009-05-14 3 views
57

Я пытаюсь понять отношения has_one в RoR.Разница между has_one и belongs_to в Rails?

Скажем, у меня есть две модели - 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 модели?

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

+1

один хороший [блог здесь] (http://requiremind.com/differences-between-has-one-and-belongs-to-in-ruby-on-rails/) для того же! –

+0

Неверный код, должен быть 'has_one: cell' и' belongs_to: person' там должно быть ** не ** быть пробелом между двоеточием и следующим словом. – Josh

ответ

142

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

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 

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

+0

Хороший ответ. Увидев ваш ответ, я понимаю, что прочитал половину вопроса. Извините, но рад, что вы вскочили. + 10 –

+5

Мне пришлось посмотреть это миллиард раз. Хотелось бы, чтобы они поняли, что называет немного лучше, чтобы было более ясно, куда идти. –

+18

Отлично, теперь я знаю два неправильных ответа. Было бы лучше показать «правильный» способ показать это. Просто говорю'. – y0mbo

7

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

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

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

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

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

+0

Лучшая строка, которую я прочитал сегодня: «Если вы добавите« принадлежит », значит, вы получили двунаправленную связь. Это означает, что вы можете получить человека из ячейки и ячейки от человека». +1 –