多対多の関係は、ember-dataではまだサポートされていません。現時点では、考えられる回避策の1つは、結合テーブルを手動で管理することです。
A = DS.Model.extend({
abs: DS.hasMany('Ab'),
bs: function () {
return this.get('abs').getEach('b');
}
});
Ab = DS.Model.extend({
a: DS.belongsTo('A'),
b: DS.belongsTo('b')
});
B = DS.Model.extend({
abs: DS.hasMany('Ab'),
bs: function () {
return this.get('abs').getEach('a');
}
});
これは出発点にすぎません。次に、レコードを正常に送信/受信/永続化するために、モデルとアダプターをカスタマイズする必要があります。
たとえば、このアプリでは{ includedJoin: true }
、hasManyリレーション内にオプションを導入し、結合テーブルをJoinModelとして宣言します。
A = DS.Model.extend({
abs: DS.hasMany('Ab', {includeJoin: true}),
...
});
DS.JoinModel = DS.Model.extend();
Ab = DS.JoinModel.extend({
... belongsTo relationships ...
});
次に、アダプタで、ストア内の結合テーブルのライフサイクルを無視するために、create / update/deleteメソッドをオーバーライドします
createRecords: function (store, type, records) {
if (!DS.JoinModel.detect(type)) {
this._super(store, type, records);
}
}
addHasMany
最後に、シリアライザーでは、結合データを親モデルの埋め込みIDとしてサーバーに送信するために、関数をオーバーライドします。
addHasMany: function (hash, record, key, relationship) {
var
options = relationship.options,
children = [];
//we only add join models, use of `includeJoin`
if (options.includedJoin) {
record.get(relationship.key).forEach(function (child) {
children.pushObject(child.toJSON({
includeId: true
}));
});
hash[key] = children;
}
}
サーバー側では、ActiveModelSerializerでRailsを使用しているため、親モデルを更新するときに、結合関係を手動で管理し、結合テーブルのエントリを作成/削除する場合に、少しトリッキーなカスタマイズを行うだけです。