0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ember DS.Store#createRecordと#pushの違いに気をつけよう

0
Posted at

はじめに

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で複数端末の状態を同期するような場合に起きがちなバグだと思います。くれぐれも気をつけましょう!(自分はやってしまいました・・・)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?