bugfix> node.js > 投稿

関連する2つのモデル、CustomersとAddressesがあります。この問題は、関連する住所を持つ顧客を作成しようとしたときに最初に発見されました。この目的のために、1人の顧客が複数の住所を持つことができます。新しい顧客を作成するときは、顧客の作成と同時に住所を作成する必要があります。

ドキュメントを掘り下げて、できる限り最善の関係を設定しましたが、これで十分に機能するように見えましたが、モジュールに両方のモデル(つまり、ルート/コントローラー)を含めると、循環参照を取得していました。

簡単に言えば、私の研究は registry を追加するように私を導きます私の bookshelf.js へのプラグインファイル。これは当時働いていましたが、今では私の Address のように見えます顧客で参照されているモデルは適切にエクスポートされません。

これが私の現在の設定の抜粋です

// bookshelf.js
const bookshelf = require('bookshelf')(knex);
bookshelf.plugin([
  'registry',
]);
module.exports = bookshelf;

// customers.js
const bookshelf = require('../bookshelf');
const Address = require('./address');
const Customer = bookshelf.Model.extend({
  tableName: 'customers',
  addresses: function () {
    return this.hasMany('Address');
  },
}, {
  customCreate: function (attributes) {
    return this.forge(attributes)
      .save()
      .tap(c => {
        return Address.forge(attributes)
          .save({
            customer_id: c.get('id'),
          });
      })
  }
});
module.exports = bookshelf.model('Customer', Customer);

// address.js
const bookshelf = require('../bookshelf');
const Customer = require('./customer');
const Address = bookshelf.Model.extend({
  tableName: 'addresses',
  customer: function () {
    return this.belongsTo('Customer');
  }
});
module.exports = bookshelf.model('Address', Address);

Customer.customCreate() を実行するときに気づき始めました 、 Address.forge is not a function というエラーが表示されました 。私はいくつかのコンソールログを customer.js に投げましたファイルし、その Address を見ました空のオブジェクト( {}customer.js 内で参照されている場合 。ただし、他の場所では、適切なBookshelfモデルが返されます。

適切に必要になる前に顧客で住所モデルを使用しようとしているように見えます。これにより、プロジェクトとモデルを適切に構造化しているのか、変更する必要があるのか​​疑問に思いました。

回答 1 件
  • 循環参照の問題があります。そのような問題が発生しないようにモデルを構成する最良の方法は、単一のファイルでのアプリの初期化中にモデルをすべてロードすることです。 index.js  モデルのディレクトリで、各オブジェクトをオブジェクトにアタッチし、そのオブジェクトをエクスポートします。それからちょうど require()  そのファイルと単一の場所ですべてのモデルへのアクセスを取得します。

    ただし、はるかに簡単な方法で問題を解決するには、 customCreate() に1つの変更を加えるだけです。  方法:

    customCreate: function (attributes) {
      return this.forge(attributes)
        .save()
        .tap(c => this.related('addresses').create(attributes))
      }
    }
    
    

    これは Collection.create を利用します  コレクション内に新しいモデルを簡単に作成するメソッド。リレーションで使用されるため、正しい外部キーも設定されます。

    Registryプラグインは循環依存関係の問題からあなたを救うわけではありませんが、以下の方法でモデルを書くことができます。避ける それら。

あなたの答え