pivotalexperimental / desert

Desert is a component framework for Rails that allows your plugins have a Rails app like directory structure, routes, migrations, and dependencies.
http://desert.rubyforge.org
186 stars 31 forks source link

ActiveRecord::Base.send(:sanitize_sql, ...) in Rails 2.3.8 #10

Open smlsml opened 13 years ago

smlsml commented 13 years ago

In versions beyond 2.3.2 (not sure exactly which one - definitely by 2.3.8) sanitize_sql expects to be operating on a subclass of ActiveRecord::Base. The attempt to call the method directly on ActiveRecord::Base causes:

undefined method abstract_class?' for Object:Class gems/activerecord-2.3.8/lib/active_record/base.rb:2242:inclass_of_active_record_descendant' gems/activerecord-2.3.8/lib/active_record/base.rb:1492:in base_class' gems/activerecord-2.3.8/lib/active_record/base.rb:1164:inreset_table_name' gems/activerecord-2.3.8/lib/active_record/base.rb:1160:in table_name' gems/activerecord-2.3.8/lib/active_record/base.rb:3154:inquoted_table_name' gems/ar-extensions-0.9.2/lib/ar-extensions/finders.rb:22:in `sanitize_sql' ...

This comes from:

This is a case where calling a non-public method using .send eventually comes back to bite you. The query in question only has two values - using the connection adapter (connection.quote()) to quote the values directly would be the better solution.

smlsml commented 13 years ago

Replace insert_sql = ActiveRecord::Base.send(... with:

      insert_sql = 'INSERT INTO %s(plugin_name, version) VALUES(%s, %s)' % [
        Desert::PluginMigrations::Migrator.schema_migrations_table_name,
        ActiveRecord::Base.connection.quote(plugin_name),
        ActiveRecord::Base.connection.quote(Integer(migration_version.split("_").first.sub(/^0*/, '')))]
      execute insert_sql