web-dev-qa-db-fra.com

Différence entre HasOne et BelongsTo dans la suite ORM

Je développe une application sails.js avec suite ORM. Je suis un peu confus quant au moment où BelongsTo et HasOne doivent être utilisés.

La documentation indique que:

Les associations appartiennent à sont des associations où la clé étrangère pour la relation un-à-un existe sur le modèle source.

Les associations HasOne sont des associations dans lesquelles la clé étrangère pour la relation un-à-un existe sur le modèle cible.

Y a-t-il une autre différence en dehors de l'endroit où elles sont spécifiées? Le comportement continue-t-il d'être le même dans les deux cas?

36
Jaseem Abbas

C'est un problème plus universel.

La principale différence est sémantique. vous devez décider quelle est la relation (un exemple stupide):

L'homme n'a qu'un seul bras droit. Le bras droit appartient à un seul homme.

Le dire inversement semble un peu bizarre:

Le bras droit a un homme. Un homme appartient au bras droit.

Vous pouvez avoir un homme sans bras droit. Mais seul le bras droit est inutile.

Dans la suite, si RightArm et Men sont des modèles, cela peut ressembler à:

Man.hasOne(RightArm);
RightArm.belongsTo(Man);

Et comme vous le constatez, il existe également une différence dans la structure de la table db:

BelongsTo ajoutera la clé étrangère sur la source où hasOne ajoutera sur la cible (Sequelize crée une nouvelle colonne 'ManId' dans la table 'RightArm', mais ne crée pas la colonne 'RightArmId' dans la table 'Man' ).

Je ne vois plus de différences.

68
Krzysztof Sztompka

Je suis d'accord avec Krzysztof Sztompka sur la différence entre:

Man.hasOne(RightArm);
RightArm.belongsTo(Man);

Je voudrais répondre Yangjun Wang question:

Donc, dans ce cas, dois-je utiliser Man.hasOne(RightArm); ou RightArm.belongsTo(Man);? Ou les utiliser tous les deux?

Il est vrai que la relation Man.hasOne(RightArm); et RightArm.belongsTo(Man); font la même chose - chacune de ces relations ajoutera la clé étrangère manId à la RightArm table.

Du point de vue de la couche de base de données physique, ces méthodes font la même chose, et cela ne fait aucune différence pour notre base de données quelle méthode exacte nous utiliserons.

Alors, quelle est la différence? La principale différence réside sur la couche de l'ORM (dans notre cas, c'est Sequalize ORM, mais la logique ci-dessous s'applique à Laravel Eloquent ORM ou même à Ruby's Active Record) ORM).

En utilisant la relation Man.hasOne(RightArm);, nous serons en mesure de remplir le RightArm de l'homme en utilisant le modèle Man. Si cela suffit pour notre application, nous pouvons arrêter avec et n'ajouter pas la relation RightArm.belongsTo(Man); au modèle RightArm.

Mais que se passe-t-il si nous devons obtenir le propriétaire du RightArm? Nous ne pourrons pas le faire en utilisant le modèle RightArm sans définir la relation RightArm.belongsTo(Man); sur le modèle RightArm.

Un autre exemple sera les modèles User et Phone. En définissant la relation User.hasOne(Phone), nous pourrons remplir notre UserPhone. Sans définir la relation Phone.belongsTo(User), nous ne pourrons pas remplir le propriétaire de notre Phone (par exemple notre User). Si nous définissons la relation Phone.belongsTo(User), nous pourrons obtenir le propriétaire de notre Phone.

Nous avons donc ici la principale différence: si nous voulons pouvoir remplir les données des deux modèles, nous devons définir les relations (hasOne et belongsTo) sur les deux. S'il nous suffit d'obtenir, par exemple, User's Phone, mais pas Phone's User, nous pouvons définir uniquement User.hasOne(Phone) relation sur le modèle User.

La logique ci-dessus s'applique à tous les ORM qui ont des relations hasOne et belongsTo.

J'espère que cela clarifie votre compréhension.

51
Vladyslav Turak