komagata さんの記事で知って以来、便利に使わせていただいている railswhere というプラグインがあるのですが (timcharper さんの笑顔が素敵)、Rails 2.3.3 にしたら動かなくなってしまいました。
where.and("name LIKE ?", "%#{ name }%")
みたいな部分で
undefined method `abstract_class?' for Object:Class
というエラーになります。
バックトレースとソースを追いかけていったところ、上のような Array 形式で条件指定をしたときに railswhere が
@criteria = ActiveRecord::Base.send(:sanitize_sql, criteria)
と ActiveRecord::Base#sanitize_sql (ActiveRecord::Base#sanitize_sql_for_conditions のエイリアス) を呼び出すのですが、こいつが 2.3.2 と 2.3.3 で変わっています。
def sanitize_sql_for_conditions(condition) # 2.3.2 (..snip..) end def sanitize_sql_for_conditions(condition, table_name = quoted_table_name) # 2.3.3 (..snip..) end
なんか第 2 引数ができてます。
で、quoted_table_name が呼ばれるせいで最終的に例外が発生してしまいます。
ただ、この第 2 引数は第 1 引数が Array のとき使われないので
@criteria = ActiveRecord::Base.send(:sanitize_sql, criteria, nil)
とかやっておけば解決します。
というわけで、config/initializers に railswhere_patch.rb みたいなのを置きました。
class Where class Clause def initialize(criteria, conjuction = "AND") # :nodoc: @conjuction=conjuction.upcase criteria = criteria.first if criteria.class==Array && criteria.length==1 if criteria.class==Array # if it's an array, sanitize it @criteria = ActiveRecord::Base.send(:sanitize_sql, criteria, nil) else @criteria = criteria.to_s # otherwise, run to_s. If it's a recursive Where clause, it will return the sql we need end end end end