読者です 読者をやめる 読者になる 読者になる

Going Rails-way

Ruby on Rails 道を突き詰めたい

クラスメソッド increment_counter と インスタンスメソッドincrement!

実際の動作

increment_counter

irb(main):001:0> Post.increment_counter(:comments_count, 1)
  SQL (4.1ms)  UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1 WHERE "posts"."id" = ?  [["id", 1]]

increment!

irb(main):001:0> post = Post.create
   (0.1ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "posts" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", 2017-03-02 02:37:16 UTC], ["updated_at", 2017-03-02 02:37:16 UTC]]
   (3.9ms)  commit transaction
=> #<Post id: 1, title: nil, comments_count: nil, created_at: "2017-03-02 02:37:16", updated_at: "2017-03-02 02:37:16">
irb(main):002:0> post.title = 'Hoge'
=> "Hoge"
irb(main):003:0> post.increment!(:comments_count, 1)
  SQL (4.1ms)  UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1 WHERE "posts"."id" = ?  [["id", 1]]
=> #<Post id: 1, title: "Hoge", comments_count: 1, created_at: "2017-03-02 02:37:16", updated_at: "2017-03-02 02:37:16">
irb(main):004:0> post.reload
  Post Load (0.3ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<Post id: 1, title: nil, comments_count: 1, created_at: "2017-03-02 02:37:16", updated_at: "2017-03-02 02:37:16">

Rails4との違い

  • Rails4ではincrement!で他の属性と同時に更新できた
  • Rails4ではincrement!COALESCE関数が使われず、comments_count = 1のようなクエリだった

まとめ

  • increment!の場合タイムスタンプが更新されるが、increment_counterは更新されない
  • どちらも他の属性と同時に(1つのUPDATEで)更新することは、できない
    • Rails4ではできるけど、incrementという名前からして正しくない使い方と考えておこう