始终从 Bookshelf.js 中的相关模型获取

Always fetch from related models in Bookshelf.js

我希望 baffle.where({id: 1}).fetch() 始终获取 typeName 属性作为 baffle 模型的一部分,而不是每次都明确地从 baffleType 中获取它。

以下对我有用,但如果直接获取 baffle 模型而不是通过关系,withRelated 似乎会加载关系:

let baffle = bookshelf.Model.extend({
    constructor: function() {
        bookshelf.Model.apply(this, arguments);

        this.on('fetching', function(model, attrs, options) {
            options.withRelated = options.withRelated || [];
            options.withRelated.push('type');           
        });
    },

    virtuals: {
        typeName: {
            get: function () {
                return this.related('type').attributes.typeName;
            }
        }
    },
    type: function () {
        return this.belongsTo(baffleType, 'type_id');
    }
});

let baffleType = bookshelf.Model.extend({});

正确的做法是什么?

回购问题与 Fetched 事件有关,但是 Fetching 事件运行良好 (v0.9.2)

举个例子,如果你有第三个模型,比如

var Test = Bookshelf.model.extend({
   tableName : 'test',
   baffleField : function(){
       return this.belongsTo(baffle)
   } 
})

然后执行Test.forge().fetch({ withRelated : ['baffleField']}),挡板上的fetching事件将会触发。但是 ORM 不会包含 type(子相关模型),除非您通过

明确告诉它这样做
Test.forge().fetch({ withRelated : ['baffleField.type']})

但是,如果 N QueryN records 制作 try to avoid,我会这样做。

更新 1

我说的和你在 fetching 活动中所做的一样,比如

fetch: function fetch(options) {
   var options = options || {}
   options.withRelated = options.withRelated || [];
   options.withRelated.push('type');    
    // Fetch uses all set attributes.
   return this._doFetch(this.attributes, options);
}

model.extend 中。但是,如您所见,这可能会在 version 更改时失败。

这个问题太老了,但我还是要回答。

我通过添加一个新函数 fetchFull 解决了这个问题,这让事情变得非常干燥。

let MyBaseModel = bookshelf.Model.extend({
  fetchFull: function() {
    let args;
    if (this.constructor.withRelated) {
      args = {withRelated: this.constructor.withRelated};
    }
    return this.fetch(args);
  },
};

let MyModel = MyBaseModel.extend({
    tableName: 'whatever',
  }, {
    withRelated: [
      'relation1',
      'relation1.related2'
    ]
  }
);

然后,无论何时查询,您都可以调用 Model.fetchFull() 来加载所有内容,或者在您不想影响性能的情况下,您仍然可以求助于 Model.fetch() .