rails: ActiveSupport::Cache::Store(s) fails to autoload classes
Environment:
- Ruby 1.9.3-p327 (happens also in p0)
- Rails 3.2.8 (happens also in 3.2.3)
Steps to reproduce:
- create a new project using: rails new autoload_bug
- create some model: rails g model user
rails c
and then type this code:
Rails.cache.write("test",User)
- close that irb,
rails c
and type:
Rails.cache.read("test")
Expected:
This should work like any other code that depends on Rails autoloading.
Actual:
It fails with the following error:
ArgumentError: undefined class/module User
from /home/uriel/.rvm/gems/ruby-1.9.3-p0/gems/activesupport-3.2.8/lib/active_support/cache.rb:587:in `load'
from /home/uriel/.rvm/gems/ruby-1.9.3-p0/gems/activesupport-3.2.8/lib/active_support/cache.rb:587:in `value'
from /home/uriel/.rvm/gems/ruby-1.9.3-p0/gems/activesupport-3.2.8/lib/active_support/cache.rb:324:in `block in read'
from /home/uriel/.rvm/gems/ruby-1.9.3-p0/gems/activesupport-3.2.8/lib/active_support/cache.rb:520:in `instrument'
from /home/uriel/.rvm/gems/ruby-1.9.3-p0/gems/activesupport-3.2.8/lib/active_support/cache.rb:315:in `read'
from (irb):1
from /home/uriel/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.8/lib/rails/commands/console.rb:47:in `start'
from /home/uriel/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.8/lib/rails/commands/console.rb:8:in `start'
from /home/uriel/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.8/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Why this is important?
This is important in development (in production config.cache_classes = true takes care of this) because if I just start my rails server and the first requests fetches some instance that the class wasn’t already loaded (typical case the User object) it will crash.
I have seen other people ran into this problem and their conclusion was either enable config.cache_classes (yuck) or loading all the models at app start.
Note: I used the class and not an instance as creating an instance requires creating a database table and I wanted to keep it simple. It happens with instances too.
The source of this bug:
All stores (from what I checked) works with Marshal#load and it seems the autoloading mechanism in rails doesn’t work for Marshal#load (I guess because it is native code)
Related links:
Other people that had this bug: http://www.philsergi.com/2007/06/rails-memcached-undefinded-classmodule.html http://stackoverflow.com/questions/4202352/memcached-problem-with-rails-3-object-isnt-being-deserialized-the-second-time http://blog.endpoint.com/2012/08/rails-3-activerecord-caching-bug-ahoy.html
Possible solution: http://stackoverflow.com/questions/3531588/memcached-as-an-object-store-in-rails
About this issue
- Original URL
- State: closed
- Created 12 years ago
- Comments: 15 (14 by maintainers)
Commits related to this issue
- Patched Marshal#load to work with constant autoloading (active_support/dependecies.rb) (issue #8167) — committed to urielka/rails by urielka 12 years ago
- Patched Marshal#load to work with constant autoloading (active_support/dependecies.rb) (issue #8167) Conflicts: activesupport/CHANGELOG.md activesupport/lib/active_support/cache/mem_cache_store.rb ... — committed to dementrock/rails by urielka 12 years ago
I’m having this problem in my Rails 3.2 application.
Rather than monkey patching Rails in my application to solve it, I would like to send a PR and have it fixed in the next minor.
Would you be interested in merging that PR?
Is there any plan to back-port this on Rails 3.2 ?