2009-05-14 18 views
57

Próbuję zrozumieć relację has_one w RoR.Różnica między has_one i belongs_to w Rails?

Powiedzmy mam dwa modele - Person i Cell:

class Person < ActiveRecord::Base 
    has_one :cell 
end 

class Cell < ActiveRecord::Base 
    belongs_to :person 
end 

mogę po prostu użyć has_one :person zamiast belongs_to :person w Cell modelu?

Czy to nie to samo?

+1

jeden dobry [blog tutaj] (http://requiremind.com/differences-between-has-one-and-belongs-to-in-ruby-on-rails/) dla tego samego! –

+0

Powyższy kod jest niepoprawny, powinien być 'has_one: cell' i' belongs_to: person' powinien ** nie ** być spacją między dwukropkiem a następnym słowem. – Josh

Odpowiedz

142

Nie, nie są wymienne i istnieją pewne rzeczywiste różnice.

belongs_to oznacza, że ​​klucz obcy znajduje się w tabeli dla tej klasy. Tak więc belongs_to może TYLKO iść w klasie, która posiada klucz obcy.

has_one oznacza, że ​​istnieje klucz obcy w innej tabeli, która odwołuje się do tej klasy. Tak więc has_one może TYLKO przejść w klasie, do której odwołuje się kolumna w innej tabeli.

Więc to jest źle:

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 

Więc to:

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 

Dla stowarzyszenia dwukierunkowy, trzeba po jednym z każdego, a oni muszą iść we właściwym klasie. Nawet w przypadku stowarzyszenia jednokierunkowego ważne jest, którego z nich używasz.

+0

Dobra odpowiedź. Widząc twoją odpowiedź, zdałem sobie sprawę, że przeczytałem połowę pytania. Przykro mi, ale cieszę się, że wskoczyłeś. + 10 –

+5

Musiałem to sprawdzić miliard razy. Chciałbym, żeby wymyślili trochę lepiej, żeby było jasne, dokąd się udaje. –

+18

Świetnie, teraz znam dwie błędne odpowiedzi. Byłoby lepiej pokazać "prawidłowy" sposób, aby to pokazać. Tylko mówię'. – y0mbo

7

Korzystanie z obu pozwala uzyskać informacje z modeli Person i Cell.

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

Jeśli dodasz "belongs_to", otrzymasz dwukierunkowe powiązanie. Oznacza to, że możesz dostać osobę z komórki i komórkę od osoby.

Nie ma prawdziwej różnicy, oba podejścia (zi bez "belongs_to") korzystają z tego samego schematu bazy danych (pole person_id w tabeli bazy danych komórek).

Podsumowując: nie dodawaj "belongs_to", chyba że potrzebujesz dwukierunkowych powiązań między modelami.

+0

Najlepsza linia, którą przeczytałem dzisiaj: "Jeśli dodasz" belongs_to ", otrzymujesz dwukierunkowe powiązanie, co oznacza, że ​​możesz dostać osobę z komórki i komórkę od osoby." +1 –