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

Node.js 始终从Bookshelf.js中的相关模型获取,node.js,bookshelf.js,knex.js,Node.js,Bookshelf.js,Knex.js,我希望buzzle.where({id:1}).fetch()始终获取typeName属性作为buzzle模型的一部分,而不必每次都从buzzletype显式获取它 以下内容适用于我,但如果直接获取模型,而不是通过关系获取,则with related似乎将加载关系: let baffle = bookshelf.Model.extend({ constructor: function() { bookshelf.Model.apply(this, arguments);

我希望
buzzle.where({id:1}).fetch()
始终获取
typeName
属性作为
buzzle
模型的一部分,而不必每次都从
buzzletype
显式获取它

以下内容适用于我,但如果直接获取
模型,而不是通过关系获取,则
with related
似乎将加载关系:

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({});

正确的方法是什么?

回购问题与
提取事件相关,但是
提取事件工作正常
(v0.9.2)

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

var Test = Bookshelf.model.extend({
   tableName : 'test',
   baffleField : function(){
       return this.belongsTo(baffle)
   } 
})
然后执行
Test.forge().fetch({withRelated:['挡板字段]]})
,挡板上的
fetching
事件将触发。但是,
ORM
将不包括
类型
(子相关模型),除非您通过

Test.forge().fetch({ withRelated : ['baffleField.type']})
但是,如果它对
N条记录进行
N查询
,我会
尽量避免这种情况

更新1

我说的和你在
获取
事件中做的一样

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);
}

模型中。扩展
。但是,正如您所看到的,这可能会在
版本更改时失败。

这个问题非常古老,但我还是在回答

我通过添加一个新的函数来解决这个问题,
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()

关于
获取
的观点很好,谢谢。因此,如果我想保持业务逻辑干燥并跳过所有
fetch()
调用中的
{withRelated:…}
部分,那么修改
选项。withRelated
是唯一的选项吗?性能在应用程序的这一部分并不重要。@estus我认为是的。然而,我已经使用sequelize一段时间了,所以不能确定。做同样事情的另一种方法是在
model.extend
中重写
(对于JS来说不是一个好词)fetch方法。然而,使用
获取
事件更像是一种书架式的方法。重写方法更简洁,但在版本升级/降级时可能会失败。当“挡板”作为关系加载时,似乎触发了
获取
,但没有加载嵌套关系,因此应在每个父模型中指定
获取
。您能为覆盖的
获取添加一个示例吗?它是否应该像
fetch:function(…args){return bookshelf.Model.prototype.fetch.bind(this)(…args)}
?谢谢,它看起来不错,我想这就是
\u doFetch
存在的原因。谢谢,永远不会太晚。