ActiveRecord: IS NULL

: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))
        enddef 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