如何使用 Bookshelf 在单个事务中处理和更新 collection 中的所有模型?
How to process and update all models in a collection, in a single transaction, with Bookshelf?
我需要遍历 Bookshelf collection 中的所有模型,计算一些信息,然后将该信息存储回每个模型。重要的是我在单个事务中执行此操作,以便在错误时回滚。
我 运行 遇到的问题是我真正能想到的唯一方法是 Promise.map
(Bluebird),但书架 collection 不行传递给地图。例如,这不起作用(Thing
是模型,Promise
是蓝鸟承诺):
Bookshelf.transaction(function (t) {
return Thing.fetchAll({transacting:t}).then(function (things) {
return Promise.map(things, function (thing) {
return thing.save({
value: computeSomeValueSync(thing)
}, {
transacting: t
});
});
});
}).tap(function () {
console.log("update complete");
});
因为things
不能传递给Promise.map
,而且书架API里好像也没有什么东西可以从一个collection...
我该怎么做?
好吧,我至少找到了一个解决方案。
第一步是编写一个函数来计算和保存值,并使其成为书架模型的成员。因此,对于我的 post 中的示例,我将在扩展模型时在 Thing
中定义以下函数:
... = bookshelf.Model.extend({
...
updateSomeValue: function (options) {
return this.save({
value: computeSomeValueSync(this)
}, options);
}
});
其中 options
是传递给保存的选项,我们可以用它来传递交易。很容易。 然后,我们可以用Collection#invokeThen
做相当于Promise.map
的事情,像这样:
Bookshelf.transaction(function (t) {
return Thing.fetchAll({transacting:t}).then(function (things) {
return things.invokeThen("updateSomeValue", {transacting:t});
});
}).tap(function () {
console.log("update complete");
});
那里,invokeThen
本质上做了我打算用 Promise.map
做的事情——returns 一旦 Thing#updateSomeValue
返回的所有承诺都得到履行,returns 承诺就会兑现.
只是有点不方便,因为我必须添加模型方法,但它确实至少有点意义。界面有点奇怪,因为文档很难拼凑在一起。但是,至少这是可能的。
仍然对其他想法持开放态度。
我需要遍历 Bookshelf collection 中的所有模型,计算一些信息,然后将该信息存储回每个模型。重要的是我在单个事务中执行此操作,以便在错误时回滚。
我 运行 遇到的问题是我真正能想到的唯一方法是 Promise.map
(Bluebird),但书架 collection 不行传递给地图。例如,这不起作用(Thing
是模型,Promise
是蓝鸟承诺):
Bookshelf.transaction(function (t) {
return Thing.fetchAll({transacting:t}).then(function (things) {
return Promise.map(things, function (thing) {
return thing.save({
value: computeSomeValueSync(thing)
}, {
transacting: t
});
});
});
}).tap(function () {
console.log("update complete");
});
因为things
不能传递给Promise.map
,而且书架API里好像也没有什么东西可以从一个collection...
我该怎么做?
好吧,我至少找到了一个解决方案。
第一步是编写一个函数来计算和保存值,并使其成为书架模型的成员。因此,对于我的 post 中的示例,我将在扩展模型时在 Thing
中定义以下函数:
... = bookshelf.Model.extend({
...
updateSomeValue: function (options) {
return this.save({
value: computeSomeValueSync(this)
}, options);
}
});
其中 options
是传递给保存的选项,我们可以用它来传递交易。很容易。 然后,我们可以用Collection#invokeThen
做相当于Promise.map
的事情,像这样:
Bookshelf.transaction(function (t) {
return Thing.fetchAll({transacting:t}).then(function (things) {
return things.invokeThen("updateSomeValue", {transacting:t});
});
}).tap(function () {
console.log("update complete");
});
那里,invokeThen
本质上做了我打算用 Promise.map
做的事情——returns 一旦 Thing#updateSomeValue
返回的所有承诺都得到履行,returns 承诺就会兑现.
只是有点不方便,因为我必须添加模型方法,但它确实至少有点意义。界面有点奇怪,因为文档很难拼凑在一起。但是,至少这是可能的。
仍然对其他想法持开放态度。