Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #7606 (new defect)

Opened 2 years ago

Last modified 2 years ago

[PATCH] QueryCache no longer working

Reported by: kyz Assigned to: core
Priority: normal Milestone: 2.x
Component: ActiveRecord Version: edge
Severity: normal Keywords: querycache query_cache caching connection_adapters
Cc:

Description

I'm trying to use the excellent idea of the QueryCache rather than reimplement the wheel (I want to use the query cache for some tables which rarely change, but avoid it for regularly changing tables)

class MyRarelyChangingThingy < ActiveRecord::Base
   establish_connection :adapter => mysql, ...
     :query_cache => true
 end

(Alternatively, defining it as a specialised database adapter):

module ActiveRecord
  class Base
    def self.cached_connection(config)
      config = config.symbolize_keys
      raise ArgumentError, "No connection specified" unless
        config.has_key? :connection
      QueryCache.new(config[:connection])
    end
  end
end

class MyRarelyChangingThingy < ActiveRecord::Base
  establish_connection :adapter => 'cached', :connection => self.connection
end

However, my attempts always fail at the same problem:

NoMethodError: undefined method `symbolize_keys' for #<ActiveRecord::ConnectionAdapters::MysqlAdapter:0xb7736a4c>
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/query_cache.rb:41:in `send'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/query_cache.rb:41:in `method_missing'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:207:in `establish_connection'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:266:in `connection_without_query_cache='
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/query_cache.rb:54:in `connection='
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:262:in `connection_without_query_cache='
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/query_cache.rb:54:in `connection='
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:230:in `retrieve_connection'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:78:in `connection'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/base.rb:1140:in `add_limit!'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/base.rb:1102:in `construct_finder_sql'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/base.rb:997:in `find_every'
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/base.rb:418:in `find'

The reason for this seems to be that assigning a connection to a class now believes ONLY children classes of AbstractAdapter can be valid connections, which QueryCache isn't. QueryCache is wrongly presumed to be a connection specification rather than an connection itself.

Rather than make QueryCache a child class of AbstractAdapter (which would inherit a number of functions and mask them rather than pass them on to the real connection), I changed the inheritance check. Here is the patch:

Index: trunk/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
===================================================================
--- trunk/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb       (revision 6176)
+++ trunk/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb       (working copy)
@@ -255,7 +255,7 @@

     # Set the connection for the class.
     def self.connection=(spec) #:nodoc:
-      if spec.kind_of?(ActiveRecord::ConnectionAdapters::AbstractAdapter)
+      if spec.kind_of?(ActiveRecord::ConnectionAdapters::AbstractAdapter) or spec.kind_of?(ActiveRecord::QueryCache)
         active_connections[name] = spec
       elsif spec.kind_of?(ConnectionSpecification)
         config = spec.config.reverse_merge(:allow_concurrency => @@allow_concurrency)

Attachments

connection_specification.patch (0.9 kB) - added by kyz on 02/21/07 10:41:13.
Patch to activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb

Change History

02/21/07 10:41:13 changed by kyz

  • attachment connection_specification.patch added.

Patch to activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb

02/21/07 10:48:04 changed by kyz

  • keywords set to querycache query_cache caching connection_adapters.