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.


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)
)

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.


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


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.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.