今回は特定のレコードをインクリメント(カウントアップ)することができるメソッド、incrementメソッドについてまとめました。カウントアップ処理のincrementの反対にカウントダウン処理を行うdecrementがありますが、使い方は基本的に同じになります。
incrementメソッドとは
incrementメソッドとは、特定のレコードをインクリメント(カウントアップ)することができるメソッドになります。incrementメソッドは保存処理を行わないため、incrementの後にはsaveを実行する必要があります。
# increment前
page = Page.first
page.num
=> 0
# increment後
page.increment(:num, 3)
page.save
page.num
=> 3
increment!との違い
incrementと似たメソッドとしてincrement!も存在します。
increment!メソッドはsave処理も同時に行ってくれるメソッドになるため、コールバックをスキップすることができます。
# increment!前
page = Page.first
page.num
=> 0
# increment!後
page = Page.first
page.increment!(:num, 3)
page.num
=> 3
decrement/decrement!
incrementの反対の挙動を示すメソッドにdecrement、increment!の反対の挙動を示すメソッドにはdecrement!があります。
使い方はincrement/increment!と同様なのでここでは割愛します。
page = Page.first
page.num
=> 3
# decrementの場合
page.decrement(:num, 3)
page.save
page.num
=> 0
page = Page.first
page.num
=> 3
# decrement!の場合
page.decrement!(:num, 3)
page.num
=> 0
(Rails4以前のincrement、decrement処理)
Rails4以前のincrement!/decrement!は同時実行での処理が考慮されておらず、計算にズレが生じてしまうということがありました。以下がその例になります。
# 同一モデルから生成された2つのインスタンスを作成
page1 = Page.first
page2 = Page.first
# それぞれのインスタンスを2ずつincrement!する
page1.increment!(:num, 2)
page2.increment!(:num, 2)
# 期待する値は4だが、なぜか2が出力される
Page.first.num
=> 2
このようなことから、Rails4以前はincrement!/decrement!で同時実行を考慮する場合は慎重に実装しなければならなかったり、そもそもincrement!/decrement!は使用しないという所が多かったそう。Rails5以降では同時処理が考慮された処理に変わりました。
参考: Rails5で#increment!と#decrement!が同時実行を意識した処理になった!
まとめ
- incrementとは特定のレコードをカウントアップすることができるメソッド
- increment!はincrementにsave処理も行うメソッド
- decrementとは特定のレコードをカウントダウンすることができるメソッド
- decrement!はdecrementにsave処理も行うメソッド
参考
今回は特定のレコードをインクリメント(カウントアップ)することができるメソッド、incrementメソッドについてまとめました。Rails4以前は同時実行が考慮されていない処理だったという背景も知れて個人的にも勉強になりました。