Rails3でのActiveRecordでは、一部のメソッドでSQLクエリが遅延実行される

Ruby on Rails 3ポケットリファレンスという本を先日(と言っても1〜2ヶ月ぐらい前ですが)買いました。

Ruby on Rails 3 ポケットリファレンス

Ruby on Rails 3 ポケットリファレンス

で、ちょっと暇なときは本をぱらぱら〜とめくって新しい知識を身につけようとしているのですが、そのとき、次のような記述を見つけました。

クエリメソッドは、find/all、first/lastなどのメソ度と違って、その場ではデータベースにアクセスしません。ただ、条件句を追加した結果をActiveRecord::Relationオブジェクトとして返すだけです。そして、結果が必要になったところで初めて、データベースへの問い合わせを行います(遅延ロード)

へ?何のこと?と思いながら単にその時はスルーしていました。

そんなさなか、今日「テストがうまく動かない」と言われ、調査したところ、上記に関する問題が出てきたのでここにメモしておきます。

まず、うまく動かないテスト言うのは、次のような物。

old = Product.where("name like '%hoge%'").order("created_at")
# 上のProductに対して変更を行う処理
new = Product.where("name like '%hoge%'").order("created_at")

new[0].price.should_not == old[0].price

本来は、上記のProductに対する処理を疑うのですが、どーみても正しい。で、デバック用として、oldを求めた後に、puts old.inspectしたらテストが通る。な、なんで〜と思っていたときに、先程の言葉を思い出しました。

ぐぐってみると、そういう記述もチラホラと見受けられます。

本家のところで該当記事を見つけられなかったのが残念なのですが、間違いないようです。