:conditionsのnilを含む条件を自動的に「IS NULL」に変換してくれないものかと思っていたら、条件をHashで渡した場合はきちんと変換してくれた。
activerecord-1.15.6/lib/active_record/base.rb
# Sanitizes a hash of attribute/value pairs into SQL conditions. # { :name => "foo'bar", :group_id => 4 } # # => "name='foo''bar' and group_id= 4" # { :status => nil, :group_id => [1,2,3] } # # => "status IS NULL and group_id IN (1,2,3)" # { :age => 13..18 } # # => "age BETWEEN 13 AND 18" def sanitize_sql_hash(attrs) conditions = attrs.map do |attr, value| "#{table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}" end.join(' AND ') replace_bind_variables(conditions, expand_range_bind_variables(attrs.values)) end … def attribute_condition(argument) case argument when nil then "IS ?" when Array then "IN (?)" when Range then "BETWEEN ? AND ?" else "= ?" end end
Arrayで条件を渡す場合でもreplace_bind_variables()に手を入れれば、うまく変換できそうな気がする。
activerecord-1.15.6/lib/active_record/base.rb
def replace_bind_variables(statement, values) #:nodoc: raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size) bound = values.dup statement.gsub('?') { quote_bound_value(bound.shift) } end