Feathers: 必芁な倚察倚の関係文曞を䜜成/曎新する

䜜成日 2018幎04月06日  Â·  20コメント  Â·  ゜ヌス: feathersjs/feathers

こんにちは、

私は珟圚、私たちのチヌムのためにフェザヌを評䟡しおいお、それが倧奜きです。 私はすべおのナヌスケヌスをカバヌしようずしおいたすが、倚察倚の関係を持぀゚ンティティ間の関連付けの䜜成たたは曎新を凊理する方法に困惑しおいたす。

mからnぞのリレヌションシップフェザヌの䟋の保存ず曎新をリク゚ストしたいず思いたす。

シナリオ
/ playersず/ teamsの2぀のサヌビスがありたすこれらは私が考えた任意のリ゜ヌスです。 プレヌダヌは倚くのチヌムに属しおいる可胜性があり、チヌムには倚くのプレヌダヌがいたす。 プレヌダヌずチヌムを゚レガントに関連付ける方法がわかりたせん。

次の方法を理解したいのですが。

  • チヌムにプレヌダヌを远加する
  • チヌムからプレヌダヌを削陀する

私は関連付けをうたく蚭定するこずができたす
team.model.js

...
  team.associate = function (models) {
    team.belongsToMany(models.player, {through: 'PlayerTeam'});
  };
...

player.model.js

...
  player.associate = function (models) {
    player.belongsToMany(models.team, {through: 'PlayerTeam'});
  };
...
Database Documentation

最も参考になるコメント

n:m関係は、CRUD操䜜党䜓で調敎するのに最も難しい関係です。 私はい぀も「ブログ投皿」ず「タグ」を私の叀兞的なn:m䟋で䜿甚しおいたす。 考慮しなければならない3぀の異なるシナリオがありたす。

  1. 新しいタグのみでブログ投皿を䜜成/曎新したす
  2. 既存のタグのみを䜿甚しおブログ投皿を䜜成/曎新したす
  3. 新芏タグず既存タグの組み合わせでブログ投皿を䜜成/曎新したす

#3ははるかに耇雑です。 ただし、そのシナリオを解決するこずで、最初の2぀を無料で解決できたす。 これが私がそれにアプロヌチする方法です

  • 制玄クラむアントに関する限り、タグをブログ投皿に関連付けるこずは、垞にブログ投皿サヌビスを介しお行われたす簡単にするため。 次のペむロヌドで単䞀のブログ投皿のみを曎新するずしたす。
    js { id: 123, title: 'My first blog post', body: '...', tags: [ { id: 111, text: 'tag-1' }, { id: 222, text: 'tag-2' }, { text: 'new-tag' } // new tags will not have an "id" ] }
  • ブログ投皿サヌビスでは、最初にブログ投皿を曎新するこずに重点を眮きたす。埌で䜿甚するためにタグを保存したす。 ブログ投皿を正しく曎新できるように、タグデヌタをbeforeフックに「キャッシュ」する必芁がありたす。
    js (context) => { if (context.data.tags) { context._tag_data = context.data.tags; delete context.data.tags; } return context; }
  • アフタヌフックで、タグを凊理したす。 たず、新しいタグを䜜成する必芁がありたす。
    js async (context) => { const tags = context._tag_data; if (tags && tags.length) { // tags without an "id" are considered new const existingTags = tags.filter(t => t.hasOwnProperty('id')); const newTags = tags.filter(t => !t.hasOwnProperty('id')); await tagService.create(newTags).then(createdTags => { // update the context._tag_data to contain the existing and newly created tags context._tag_data = existingTags.concat(createdTags) }) } return context; }
  • 最埌に、すべおのタグをブログ投皿に関連付けたす。
    js async (context) => { const tags = context._tag_data; if (tags && tags.length) { const blogPostId = hook.result.id; const mappings = tags.map(t => ({ tagId: t.id, blogPostId })); await postTagsService.create(mappings).then(() => { // Put the tags on the final result hook.result.tags = tags; }); } return context; }

それは_簡単_ではないように思えたすが、私はすべおのナヌスケヌスに぀いお考えるこずに倚くの時間を費やしたした。䞊蚘は、党䜓的なナヌザヌフレンドリヌな゜リュヌションに぀いお私が芋る唯䞀の方法です。 私は提案を求めおいたすが、単䞀の操䜜でデヌタを䜜成しお関連付けるこずを可胜にする確立されたナヌザビリティ芏則Wordpress、StackOverflowなどに察凊する必芁がありたす。

党おのコメント20件

カむル-それはこのように解決したすか 䟋

ありがずうございたした、

マヌク・゚ドワヌズ

3時44分PMの朚、2018幎4月5日には、カむル・コヌプランド[email protected]
曞きたした

こんにちは、

私は珟圚、私たちのチヌムのためにフェザヌを評䟡しおいお、それが倧奜きです。 私はしようずしおいたす
私たちのすべおのナヌスケヌスをカバヌし、䜜成たたは䜜成を凊理する方法に困惑しおいたす
倚察倚の関係を持぀゚ンティティ間の関連付けを曎新したす。

mからnのリレヌションシップフェザヌの保存ず曎新をリク゚ストしたい
䟋。

シナリオ
/ playersず/ teamsの2぀のサヌビスがありたすこれらは任意のリ゜ヌスです
私は考えたした。 プレヌダヌは倚くのチヌムに属しおいる可胜性があり、チヌムには倚くのチヌムがありたす
プレむダヌ。 プレヌダヌずチヌムの関連付けを凊理する方法がわかりたせん
゚レガントなファッション。

次の方法を理解したいのですが。

  • チヌムにプレヌダヌを远加する
  • チヌムからプレヌダヌを削陀する

私は関連付けをうたく蚭定するこずができたす
team.model.js

..。
team.associate = functionmodels{
team.belongsToManymodels.player、{through 'PlayerTeam'};
};
..。

player.model.js

..。
player.associate = functionmodels{
player.belongsToManymodels.team、{through 'PlayerTeam'};
};
..。

—
このスレッドにサブスクラむブしおいるため、これを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/feathersjs/feathers/issues/852 、たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/ACyd4jo95mdpY5gNYF3GtdghdDwfwG4Uks5tlp40gaJpZM4TJRE4
。

@edwardsmarkfマヌクさん、お

こんにちはカむル-画像はこ​​こから来たした
https://en.wikipedia.org/wiki/Many-to-many_data_model-倚分
githubメヌルは写真を蚱可しおいたせんか

私はあなたを正しく理解したず思いたす。

ありがずうございたした、

マヌク・゚ドワヌズ

5時51分PMに朚、2018幎4月5日には、カむル・コヌプランド[email protected]
曞きたした

@edwardsmarkf https://github.com/edwardsmarkfねえマヌク、ありがずう
手を差し䌞べる。 あなたの䟋は省略されおいるかもしれないず思いたす。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/feathersjs/feathers/issues/852#issuecomment-379118164 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/ACyd4gMY3kJiprvR3I2fRZP7LThfbvLHks5tlrwDgaJpZM4TJRE4
。

蚀及するのを忘れた

https://en.wikipedia.org/wiki/Many-to-many_data_model 

著者ず本の倚察倚の関係を1察倚のペアずしお
ゞャンクションテヌブルずの関係

あなたの関係はそれらの間の「ゞャンクションテヌブル」を埗るこずができたすか ゞャンクション
テヌブルはコメントや日付などを考えただけで保持できるかもしれたせん。

ありがずうございたした、

マヌク・゚ドワヌズ

2018幎4月5日朚曜日午埌6時4分、Mark

>>

こんにちはカむル-画像はこ​​こから来たした https 
/ Many-to-many_data_model-おそらくgithubメヌルでは蚱可されおいたせん
写真

私はあなたを正しく理解したず思いたす。

ありがずうございたした、

マヌク・゚ドワヌズ

5時51分PMに朚、2018幎4月5日には、カむル・コヌプランド[email protected]
曞きたした

@edwardsmarkf https://github.com/edwardsmarkfねえマヌク、ありがずう
手を差し䌞べる。 あなたの䟋は省略されおいるかもしれないず思いたす。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/feathersjs/feathers/issues/852#issuecomment-379118164 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/ACyd4gMY3kJiprvR3I2fRZP7LThfbvLHks5tlrwDgaJpZM4TJRE4
。

ちょっず゚ドワヌド、ありがずう。 ORM /フェザヌを䜿甚したゞャンクションテヌブルの凊理が圓面の問題です。

これが私の最善の掚枬ずSequelizeの問題を解決する方法です。 みなさんのご意芋をお聞かせください。

app.use('/team/:teamId/player/:playerId', {
    // Gives the ability to add the association
    create(data, params) {
      return app.service('team').Model.findById(params.route.teamId).then(team => {
        return app.service('player').Model.findById(params.route.playerId).then(player => {
          return team.addPlayer(player);
        });
      });
    },

    // Gives the ability to delete an association
    remove(id, params) {
      return app.service('team').Model.findById(params.route.teamId).then(team => {
        return app.service('player').Model.findById(params.route.playerId).then(player => {
          return team.removePlayer(player);
        });
      });
    }
  });

これはhttps://sequelize.slack.comでもっずよく答えられるのだろうか たたは代わりにビュヌを䜿甚したすか

䜕が最善だず刀断したかに぀いお、私に知らせおください。 それは非垞に興味深い問題です。

あなたが提案しおいるそのサヌビスは実際にはかなりきちんずしおいたす。 たた、結合テヌブルモデル甚に別のサヌビスを䜜成するこずもありたす。 @DesignByOnyxは、圌の旅行からここに䜕か掞察を持っおいるのだろうか。

新しい関連゚ントリの䜜成は、配列をcreate枡すこずで機胜するはずですが、正しいですか

みなさんからの返信ありがずうございたす。 @dafflの提案ですが、チヌムプレヌダヌのサヌビスを利甚しお、フックを介しお゚ントリを結合するこずになりたすか たた、配列を介しお新しい関連゚ントリを䜜成するこずの意味を説明しおもらえたすか

ここの@dafflは、サヌビス察ORMでの私の最良の掚枬です

サヌビス指向の方法

//AFTER HOOK: pseudo-code I haven't tested this

const {result, app} = context;

result.map(async team => {
  const players = await app.service('team-player').find({
      query: {
        teamId: team.id
      }
    }).then(results => {
       return app.service('player').find({
          query: {
            playerId: results.playerId
        });
    });

  team.players = players;
})

return context;

ORMの方法
`` `
//フック前これは機胜したす
context.params.sequelize = {
含む [ {
モデルcontext.app.service 'player'。Model、
ずしお 'プレヌダヌ'、
属性['名前']、
䜿っお {
属性[]
}
}]、
生false
};

コンテキストを返したす。

カむル-私はあなたが盎面しおいるのず同じ問題に遭遇しようずしおいるので、お願いしたす
これがどのように機胜するかを教えおください。

ありがずうございたした、

マヌク・゚ドワヌズ

11:22時金、2018幎4月6日には、カむル・コヌプランド[email protected]
曞きたした

@dafflhttps //github.com/dafflここにサヌビスずORMの私の最良の掚枬がありたす

サヌビス指向の方法

//フック埌疑䌌コヌドこれはテストしおいたせん

const {result、app} =コンテキスト;

result.mapasync team => {
constplayers = await app.service 'team-player'。find{
ク゚リ{
teamIdteam.id
}
}。thenresults => {
app.service 'player'。find{
ク゚リ{
playerIdresults.playerId
};
};

team.players =プレヌダヌ;
}

コンテキストを返したす。

ORMの方法

//フック前これは機胜したす
context.params.sequelize = {
含む [ {
モデルcontext.app.service 'player'。Model、
ずしお 'プレヌダヌ'、
属性['名前']、
䜿っお {
属性[]
}
}]、
生false
};

コンテキストを返したす。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/feathersjs/feathers/issues/852#issuecomment-379336187 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/ACyd4hzQdRSLJ5tBm7I_BkOFPDYkyhU7ks5tl7JKgaJpZM4TJRE4
。

n:m関係は、CRUD操䜜党䜓で調敎するのに最も難しい関係です。 私はい぀も「ブログ投皿」ず「タグ」を私の叀兞的なn:m䟋で䜿甚しおいたす。 考慮しなければならない3぀の異なるシナリオがありたす。

  1. 新しいタグのみでブログ投皿を䜜成/曎新したす
  2. 既存のタグのみを䜿甚しおブログ投皿を䜜成/曎新したす
  3. 新芏タグず既存タグの組み合わせでブログ投皿を䜜成/曎新したす

#3ははるかに耇雑です。 ただし、そのシナリオを解決するこずで、最初の2぀を無料で解決できたす。 これが私がそれにアプロヌチする方法です

  • 制玄クラむアントに関する限り、タグをブログ投皿に関連付けるこずは、垞にブログ投皿サヌビスを介しお行われたす簡単にするため。 次のペむロヌドで単䞀のブログ投皿のみを曎新するずしたす。
    js { id: 123, title: 'My first blog post', body: '...', tags: [ { id: 111, text: 'tag-1' }, { id: 222, text: 'tag-2' }, { text: 'new-tag' } // new tags will not have an "id" ] }
  • ブログ投皿サヌビスでは、最初にブログ投皿を曎新するこずに重点を眮きたす。埌で䜿甚するためにタグを保存したす。 ブログ投皿を正しく曎新できるように、タグデヌタをbeforeフックに「キャッシュ」する必芁がありたす。
    js (context) => { if (context.data.tags) { context._tag_data = context.data.tags; delete context.data.tags; } return context; }
  • アフタヌフックで、タグを凊理したす。 たず、新しいタグを䜜成する必芁がありたす。
    js async (context) => { const tags = context._tag_data; if (tags && tags.length) { // tags without an "id" are considered new const existingTags = tags.filter(t => t.hasOwnProperty('id')); const newTags = tags.filter(t => !t.hasOwnProperty('id')); await tagService.create(newTags).then(createdTags => { // update the context._tag_data to contain the existing and newly created tags context._tag_data = existingTags.concat(createdTags) }) } return context; }
  • 最埌に、すべおのタグをブログ投皿に関連付けたす。
    js async (context) => { const tags = context._tag_data; if (tags && tags.length) { const blogPostId = hook.result.id; const mappings = tags.map(t => ({ tagId: t.id, blogPostId })); await postTagsService.create(mappings).then(() => { // Put the tags on the final result hook.result.tags = tags; }); } return context; }

それは_簡単_ではないように思えたすが、私はすべおのナヌスケヌスに぀いお考えるこずに倚くの時間を費やしたした。䞊蚘は、党䜓的なナヌザヌフレンドリヌな゜リュヌションに぀いお私が芋る唯䞀の方法です。 私は提案を求めおいたすが、単䞀の操䜜でデヌタを䜜成しお関連付けるこずを可胜にする確立されたナヌザビリティ芏則Wordpress、StackOverflowなどに察凊する必芁がありたす。

たた、Sequelizeを䜿甚するず、これが必芁以䞊に難しくなるず思いたす。 モデルメ゜ッドは開発者ずしお盎感的に芋えたすが、APIクラむアントの芳点からは、メ゜ッドを呌び出すのではなく、デヌタを送信するだけです。

たずえば、既存のIDを䜿甚したり、IDのリストを指定したりしお、関連付けを曎新たたは䜜成するこずはできたせん。これは非垞に盎感的ではありたせん。

私はこれず同じ問題を抱えおいたすが、䜿いやすく安党なものは芋぀かりたせんでした。

ここでも同じ問題がありたす。 @ DesignByOnyxが今のずころそのアプロヌチを採甚するこずに感謝したす。 他の誰かがこれに察する盎感的な解決策を思い付きたすか

私もこれをフォロヌしおいお、珟圚、今週新しいプロゞェクトにこれを実装しようずしおいたす

@daffl提案をありがずう、それは今のずころ私のために働いた。

ちょっずしたメモずしお、実際には@DesignByOnyxが瀺すよりも

欠点は、曎新のたびにかなりの䞍芁な䜜業を行うこずです倉曎されおいない可胜性のあるタグのリストを削陀しお保存したす。

私が考えるこずができる唯䞀の遞択肢は、曎新する前に関係を読み取り、必芁な[䜜成、曎新、削陀]の最小数を蚈算するこずです。 タグの数が倚い堎合は、それだけの䟡倀があるかもしれたせん。

別のアむデアは、関係のサヌビスを䜜成し、IDで各゚ントリを識別し、[投皿、タグ]のペアごずに個別に呌び出すこずだず思いたす。 これはネットワヌクリク゚ストでは非効率に思えたすが、抂念的にはすべおを䞀床に実行するよりも少し簡単です。

class CustomService {
  constructor(options) {
    this.options = options || {};
  }

  /**
   * <strong i="5">@params</strong> {object} data - Sent in from client
   * <strong i="6">@params</strong> {INT} data.building_id - ID of the building from the Building Model
   * <strong i="7">@params</strong> {INT} data.contact_id - ID of the contact from the Contact Model
   */
  create = async (data, params) => {
    if (isNaN(data.building_id)) {
      throw new errors.BadRequest('Building ID MUST be a Number', data);
    }
    if (isNaN(data.contact_id)) {
      throw new errors.BadRequest('Contact ID MUST be a Number', data);
    }

    const building = await this.options.building.get(data.building_id);
    const contact = await this.options.contact.get(data.contact_id);
    const buildingContacts = await building.addContact(contact);

    return buildingContacts;
  };
}

export default app => {
  app.use(
    'api/v1/building_contacts',
    new CustomService({
      building: app.service('api/v1/building'),
      contact: app.service('api/v1/contact')
    })
  );

  const buildingContactsService = app.service('api/v1/building_contacts');

  buildingContactsService.hooks(hooks);
};

私が盎面しおいる問題は、連絡先が建物にすでに存圚する堎合、郵䟿配達員にpage not found゚ラヌが発生するこずです。
連絡先が建物に远加されたこずがない堎合、これは問題なく実行されたす。

䜕か案は

  const tags = context._tag_data;
  if (tags && tags.length) {
    const blogPostId = hook.result.id;
    const mappings = tags.map(t => ({ tagId: t.id, blogPostId }));
    await postTagsService.create(mappings).then(() => {
      // Put the tags on the final result
      hook.result.tags = tags;
    });
  }

これは、䞭間テヌブル甚のフェザヌサヌビスを䜜成する必芁があるこずを意味したすか 䞍芁なサヌビスのようです。 ここでデヌタベヌスず察話する別の方法はありたすか

「関係」サヌビスが必芁であり、3番目のサヌビスずしおの䜿甚を回避するために私が行ったすべおの詊みは、無駄であるか、他のコヌドを䞍圓に困難にしたした。 これは私がn:m関係を扱ったずきに持っおいた最倧の「あはは」の瞬間

このシナリオに぀いお考えおみおください。ブログ投皿ず既存のタグがあり、2぀を関連付けたいず考えおいたす。 ブログ投皿自䜓を䜜成たたは曎新するのではなく、タグを䜜成たたは曎新するのでもありたせん。単に2぀の間の関係を定矩するだけです。 ブログサヌビスやタグサヌビスに觊れる必芁はありたせん。「blog-tags」サヌビスだけに觊れる必芁がありたす...そのためには存圚する必芁がありたす。

もう1぀のより耇雑なオプションは、ブログサヌビスたたはタグサヌビスを䜿甚しお関係を曎新しようずするこずです。 どちらを䜿いたすか それをチヌムにどのように䌝えたすか それが䞡方の方法で発生するこずを蚱可するず、維持するコヌドが2倍になり、メンタルモデルも難しくなりたす。 関係自䜓に3番目のサヌビスがある堎合、これらの問題はすべお解消されたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡