2016-12-13 3 views
1

Bookshelf 컬렉션의 모든 모델을 반복하고 정보를 계산 한 다음 해당 정보를 각 모델에 저장해야합니다. 오류를 롤백하려면 단일 트랜잭션에서이 작업을 수행하는 것이 중요합니다.Bookshelf를 사용하여 단일 트랜잭션으로 컬렉션의 모든 모델을 처리하고 업데이트하는 방법?

나는이 작업을 수행하기 위해 실제로 생각할 수있는 유일한 방법은 Promise.map (Bluebird)이지만 책꽂이 모음은 전달할 수 없습니다.

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에서 아무것도 할 수없는 것 : 예를 들어,이 작동하지 않습니다 (Thing는 모델이다 Promise는 블루 버드 약속입니다) 컬렉션에서 모델 배열을 얻을 수 있습니다. ...

어떻게하면됩니까?

답변

0

좋아요, 나는 해결책을 찾았습니다.

첫 번째 단계는 을 계산하는 함수를 작성하고은 값을 저장하고이 값을 책꽂이 모델의 구성원으로 만듭니다. 모델을 확장 할 때 그래서, 내 게시물에서, 예를 들어, 나는 Thing에 다음 함수를 정의하는 것 :

... = bookshelf.Model.extend({ 

    ... 

    updateSomeValue: function (options) { 
     return this.save({ 
      value: computeSomeValueSync(this) 
     }, options); 
    } 

}); 

options이 옵션은 우리를 통해 트랜잭션을 전달하는 데 사용할 수있는 저장 전달하는 경우. 충분히 쉬워. 다음, 우리는 다음과 같이 Collection#invokeThenPromise.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와 함께 할 의도하지 않습니다는 - 한 번에 모든 약속에 의해 반환 성취하게되는 약속을 반환 Thing#updateSomeValue이 충족됩니다.

모델 방법을 추가해야한다는 점에서 다소 불편하지만, 이 최소한의 의미를 갖습니다. 문서는 서로 조각하기가 까다로워 인터페이스가 조금 이상합니다. 그러나 적어도 가능합니다.

다른 아이디어에도 여전히 열려 있습니다.

관련 문제