Rails

ActiveRecord の where と where! (where bang) の違い

概要

おそらく Ruby on Rails4 以降に導入されている ActiveRecord::QueryMethods#where! includes! .. などについて。

違いとは

where

where は呼び出し時に新しくオブジェクトがクローンされる。

> users = User.all
> users.where(id: 1).object_id
=> 70140175157520
> users.where(id: 1).object_id
=> 70140175100600
> users.where(id: 1).object_id
=> 70140175049660

where!

where! はクローンされない。

> users.object_id
=> 70140126836880
> users.where!(id: 1).object_id
=> 70140126836880
> users.where!(id: 1).object_id
=> 70140126836880
> users.where!(id: 1).object_id
=> 70140126836880

whereでメソッドチェーンを繰り返す使い方を考えると、こちらは元のオブジェクトのクエリをどんどん書き換えていくイメージですね。

なので、破壊的メソッドを示す ! というネーミングなのだと思います。

参考

https://stackoverflow.com/questions/23950627/undocumented-activerecord-bang-methods

該当のプルリクエスト。whereは内部でwhere!を利用している。
where バージョンではオブジェクトをクローンしている。

https://github.com/rails/rails/commit/8c2c60511beaad05a218e73c4918ab89fb1804f0