はじめに
DS.Store#createRecordとはこうゆうものです。
export default Ember.Route.extend({
model() {
return this.store.createRecord("product", { id: 1, name: "foo" });
}
});
この場合、作成されたProductモデルのインスタンスはisNewフラグがtrueであり、保存されていない全く新しいオブジェクトとして扱われます。
DS.Store#pushとはこうゆうものです
export default Ember.Route.extend({
model() {
return this.store.push("product", { id: 1, name: "foo" });
}
});
基本的には1番目の引数に型名、2番目の引数にプレーンなオブジェクトを渡すことで新しいProductモデルのインスタンスを作成します。
#pushで追加したインスタンスはisNewがfalse
インスタンスの作成に#createRecordを使う場合も#pushを使う場合も、第2引数のオブジェクトにidを含めることは可能ですが、#createRecordではisNewがtrueに、#pushではisNewがfalseに設定されるためその後の#saveの挙動が異なります。
var product = this.store.createRecord("product", { id: 1, name: "foo" });
product.save(); // => XHR POST /products がとぶ
var product = this.store.push("product", { id: 1, name: "foo" });
product.save(); // XHR PUT /products/1 がとぶ
isNewがtrueならまだDBに保存されていないレコードなのでPOSTリクエストが飛んでしまいます。これがDB上でも本当にisNewならいいのですがid 1が既に保存されている場合、リクエストは成功するがサーバーの吐くjsonのidが2になったりして整合性がとれなくなるわけです。
pushで作成したばあいはisNewがfalseなのでPUTリクエストがとぶだけなので安心です。
WebSocketで複数端末の状態を同期するような場合に起きがちなバグだと思います。くれぐれも気をつけましょう!(自分はやってしまいました・・・)