J'essaie de comprendre has_one
relation dans RoR.
Disons que j'ai deux modèles - Person
et Cell
:
class Person < ActiveRecord::Base
has_one :cell
end
class Cell < ActiveRecord::Base
belongs_to :person
end
Puis-je simplement utiliser has_one :person
au lieu de belongs_to :person
dans Cell
modèle?
N'est-ce pas pareil?
Non, ils ne sont pas interchangeables et il existe de réelles différences.
belongs_to
signifie que la clé étrangère est dans la table de cette classe. Donc belongs_to
ne peut aller que dans la classe qui détient la clé étrangère.
has_one
signifie qu'il existe une clé étrangère dans une autre table qui fait référence à cette classe. Donc has_one
ne peut aller que dans une classe référencée par une colonne dans une autre table.
C'est donc faux:
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
Et c'est aussi faux:
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
La bonne façon est (si Cell
contient person_id
champ):
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
Pour une association à double sens, vous avez besoin d'un de chaque, et ils doivent aller dans la bonne classe. Même pour une association à sens unique, il importe de savoir laquelle vous utilisez.
Si vous ajoutez "appartient à", vous obtenez une association bidirectionnelle. Cela signifie que vous pouvez obtenir une personne de la cellule et une cellule de la personne.
Il n'y a pas de réelle différence, les deux approches (avec et sans "appartient à") utilisent le même schéma de base de données (un champ person_id dans la table de base de données des cellules).
Pour résumer: N'ajoutez pas "appartient à" sauf si vous avez besoin d'associations bidirectionnelles entre les modèles.
L'utilisation des deux vous permet d'obtenir des informations à la fois sur les modèles Personne et Cell.
@cell.person.whatever_info and @person.cell.whatever_info.