Quelle est la différence entre appartient_to et has_one?

Réponses:

241

Ils font essentiellement la même chose, la seule différence est de quel côté de la relation vous êtes. Si a Usera un Profile, alors dans la Userclasse que vous auriez has_one :profileet dans la Profileclasse que vous auriez belongs_to :user. Pour déterminer qui "possède" l'autre objet, regardez où se trouve la clé étrangère. On peut dire qu'un User"a" un Profileparce que la profilestable a une user_idcolonne. S'il y avait une colonne appelée profile_idsur la userstable, cependant, nous dirions que a Profilea un User, et les emplacements appartiennent_to / has_one seraient échangés.

voici une explication plus détaillée.

Ryeguy
la source
ok a du sens, has_a est une propriété, tandis qu'un appartient est plus une relation.
Blankman du
48
Donc pour le dire vraiment court: Product belongs_to Shopsignifie que la productstable a une shop_idcolonne
Yo Ludke
@ryeguy, qu'en est-il s'il s'agit d'une relation d'auto-union?
Arian Faurtosh le
49

Il s'agit de l'emplacement de la clé étrangère.

class Foo < AR:Base
end
  • Si foo belongs_to :bar, alors la table foos a une bar_idcolonne
  • Si toto has_one :bar, alors la table des barres a une foo_idcolonne

Sur le plan conceptuel, si vous avez class Aune has_onerelation avec, class Balors class Aest le parent de, par class Bconséquent, vous class Baurez une belongs_torelation avec class Apuisque c'est l'enfant de class A.

Les deux expriment une relation 1-1. La différence réside principalement dans l'emplacement de la clé étrangère, qui va sur la table de la classe déclarant la belongs_torelation.

class User < ActiveRecord::Base
  # I reference an account.
  belongs_to :account
end

class Account < ActiveRecord::Base
  # One user references me.
  has_one :user
end

Les tableaux de ces classes pourraient ressembler à quelque chose comme:

CREATE TABLE users (
  id int(11) NOT NULL auto_increment,
  account_id int(11) default NULL,
  name varchar default NULL,
  PRIMARY KEY  (id)
)

CREATE TABLE accounts (
  id int(11) NOT NULL auto_increment,
  name varchar default NULL,
  PRIMARY KEY  (id)
)
Chandan Kumar Mallik
la source
C'est à peu près la même chose que la réponse acceptée d'il y a deux ans indique déjà.
matthias krull
11
C'est à peu près une meilleure réponse.
typeoneerror
L'utilisation de Accountet Userdans cet exemple est regrettable car il arrive souvent qu'un compte puisse avoir de nombreux utilisateurs.
karmakaze
5

has_oneet belongs_tosont généralement les mêmes en ce sens qu'ils pointent vers l'autre modèle connexe. belongs_toassurez-vous que ce modèle a le foreign_keydéfini. has_ones'assure que l'autre has_foreignclé de modèle définie.

Pour être plus précis, il y a deux côtés relationship, l'un est le Owneret l'autre est Belongings. Si seulement has_oneest défini, nous pouvons obtenir son Belongingsmais pas le Ownerdepuis le belongings. Pour tracer le, Ownernous devons également définir le belongs_todans le modèle d'appartenance.

illusionniste
la source
3

Une chose supplémentaire que je veux ajouter est, supposons que nous ayons l'association de modèles suivante

class Author < ApplicationRecord has_many :books end

si nous n'écrivons que l'association ci-dessus, nous pouvons obtenir tous les livres d'un auteur particulier par,

@books = @author.books

Mais pour un livre particulier, nous ne pouvons pas obtenir l'auteur correspondant,

@author = @book.author

pour que le code ci-dessus fonctionne, nous devons également ajouter une association au modèle Book, comme ceci

class Book < ApplicationRecord
  belongs_to :author
end

Cela ajoutera la méthode «auteur» au modèle de livre.
Pour plus de détails sur les modes, consultez les guides

Somesh Sharma
la source
0

Du point de vue de la simplicité, belongs_toc'est mieux que has_oneparce que dans has_one, vous devrez ajouter les contraintes suivantes au modèle et à la table contenant la clé étrangère pour appliquer la has_onerelation:

  • validates :foreign_key, presence: true, uniqueness: true
  • ajoutez un index unique de base de données sur la clé étrangère.
Konyak
la source