AWDwR 3rd Edition によると Rails 1.2 から ActiveRecord::Base#find の :conditions に Hash を渡せるようになったようで、その際にログを眺めてたら実行される SQL の WHERE 句が IN () を使っていた。これをどこでやってんのか気になったのでソースを追ってみた。 Rails 2.3.9 で確認。
activerecord/base.rb のメソッド呼び出しを追うと以下のようになってて、
find -> find_every -> find_by_sql -> construct_finder_sql -> add_conditions! -> merge_conditions -> sanitize_sql -> (alias_method) sanitize_sql_for_conditions -> sanitize_sql_hash_for_conditions -> attribute_condition
attribute_condition の中でやってた。まぁ IN で grep すれば該当箇所はすぐ見つかるんだけど、トップダウンで追うのも流れをおさえるにはいいかなと思って。
def attribute_condition(quoted_column_name, argument) case argument when nil then "#{quoted_column_name} IS ?" when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope then "#{quoted_column_name} IN (?)" when Range then if argument.exclude_end? "#{quoted_column_name} >= ? AND #{quoted_column_name} < ?" else "#{quoted_column_name} BETWEEN ? AND ?" end else "#{quoted_column_name} = ?" end end
書籍やマニュアルであんまり詳しく述べられてない内部の挙動*1に疑問があるときはソースを読むと自信をもって機能を使えてよいですね。
RailsによるアジャイルWebアプリケーション開発 第3版
- 作者: Sam Ruby,David Heinemeier Hansson,Dave Thomas,前田修吾
- 出版社/メーカー: オーム社
- 発売日: 2009/12/01
- メディア: 単行本
- 購入: 16人 クリック: 316回
- この商品を含むブログ (39件) を見る
*1:SQL の WHERE 句がどうなるか、とか