web-dev-qa-db-ja.com

Sequelize ORMにおけるHasOneとBelongsToの違い

sails.js アプリを sequelize ORMで開発しています。 BelongsToとHasOneをいつ使用する必要があるかについて少し混乱しています。

ドキュメントは次のように述べています:

BelongsToアソシエーションは、1対1のリレーションの外部キーがソースモデルに存在するアソシエーションです。

HasOneアソシエーションは、1対1のリレーションの外部キーがターゲットモデルに存在するアソシエーションです。

指定場所以外に違いはありますか?どちらの場合も、動作は引き続き同じですか?

36
Jaseem Abbas

これはより一般的な問題です。

主な違いはセマンティックです。あなたは関係とは何かを決定する必要があります(いくつかのばかげた例):

男の右腕は1つだけです。右腕は一人の男に属しています。

それを逆に言うと少し奇妙に見えます:

右腕には男がいます。男は右腕に属しています。

あなたは右腕がなくても男を持つことができます。しかし、右腕だけでは役に立たない。

RightArmとMenがモデルの場合、逐次化すると次のようになります。

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

そして、お気づきのとおり、dbテーブルの構造にも違いがあります。

BelongsToは、ソースにforeignKeyを追加し、hasOneがターゲットに追加します(Sequelizeは、テーブル 'RightArm'に新しい列 'ManId'を作成しますが、 'Man'テーブルに 'RightArmId'列を作成しません)。

これ以上違いはありません。

68

私は Krzysztof Sztompka の違いについて同意します:

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

Yangjun Wang の質問に答えたい:

この場合、Man.hasOne(RightArm);またはRightArm.belongsTo(Man);のどちらを使用する必要がありますか?または両方を使用しますか?

Man.hasOne(RightArm);リレーションとRightArm.belongsTo(Man);のリレーションは同じことをするのは事実です-これらのリレーションのそれぞれが外部キーmanIdRightArmテーブルに追加します。

物理データベースレイヤーの観点から見ると、これらのメソッドは同じことを行い、データベースにどのメソッドを使用するかについては違いはありません。

それで、違いは何ですか?主な違いはORMのレイヤーにあります(この場合は Sequalize ORMですが、以下のロジックはLaravelの Eloquent ORMまたはRubyの Active Recordにも適用されます) ORM)。

Man.hasOne(RightArm);リレーションを使用すると、RightArmモデルを使用して男性のManを入力できます。アプリケーションでこれで十分な場合は、これで終了し、RightArm.belongsTo(Man);リレーションをRightArmモデルに追加しないでください。

しかし、RightArmの所有者を取得する必要がある場合はどうなりますか? RightArmモデルでRightArm.belongsTo(Man);関係を定義しないと、RightArmモデルを使用してこれを行うことはできません。

もう1つの例は、UserモデルとPhoneモデルです。 User.hasOne(Phone)リレーションを定義すると、UserPhoneを入力できます。 Phone.belongsTo(User)関係を定義しないと、Phoneの所有者(たとえば、User)を設定できません。 Phone.belongsTo(User)リレーションを定義すると、Phoneの所有者を取得できます。

したがって、ここに主な違いがあります。両方のモデルからデータを入力できるようにするには、両方のモデルで関係(hasOneおよびbelongsTo)を定義する必要があります。たとえば、UserPhoneではなくPhoneUserを取得するだけで十分な場合は、User.hasOne(Phone)Userモデルの関係。

上記のロジックは、hasOneおよびbelongsTo関係を持つすべてのORMに適用されます。

ご理解のほどよろしくお願いいたします。

51
Vladyslav Turak