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
存在的原因。谢谢,永远不会太晚。