jnunemaker/mongomapper — Issue #330: Can't store a MongoMapper document in a Rails cache (ActiveSupport::Cache::Store)
Author: gardelea
Created: 2011-10-25 17:06:23+00:00
State: open

I know this has been talked about in the google user group. but i wanted to create a ticket to track this feature.

the scenario is you have a `MongoMapper::Document` instance and you want to store it in a `ActiveSupport::Cache::Store` (`ActiveSupport::Cache::MemoryStore` in my case) you cannot later read any attributes from the mongomapper instance as the `ActiveSupport::Cache::Store` will `freeze` any objects placed in it.

Below is an example of what is happening in the controller to cache, and what happens after a request gets a cache hit and tries to access an attribute in the view (using slim here).

```ruby
class MyOptimizedController < ApplicationController
before_filter :load_instance

...

private

def load_instance
@thing = Rails.cache.fetch("Thing:#{params[:id]}") do
Thing.find(params[:id])
end
end

...

end
```

```
ActionView::Template::Error (can't modify frozen object):
1: .thing
2: = render :partial => @thing.show_partial
vendor/bundle/ruby/1.9.1/gems/mongo_mapper-0.9.2/lib/mongo_mapper/plugins/keys.rb:307:in `instance_variable_set'
vendor/bundle/ruby/1.9.1/gems/mongo_mapper-0.9.2/lib/mongo_mapper/plugins/keys.rb:307:in `read_key'
(eval):2:in `show_partial'
...
```

for completeness here is the MongoMapper object setup :

```ruby
class Thing
include MongoMapper::Document
timestamps!
key :show_partial, String
end
```

I tracked this down to the relevant code in MongoMapper (0.9.2) and Rails (3.0.7) :

MongoMapper's need to set instance variable whenever a key is accessed on a `MongoMapper::Document`
https://github.com/jnunemaker/mongomapper/blob/e056ca9bb71ed7b877975d3383df44efc10e61f6/lib/mongo_mapper/plugins/keys.rb#L307

and to `ActiveSupport::Cache::Store`'s need to freeze all values in its store
https://github.com/rails/rails/blob/2c3260147f90e35a6a5e3ce1b520b4de701e701e/activesupport/lib/active_support/cache.rb#L575

and lastly, at the time of this writing it seems the Rails master branch has removed the freezing behavior of the cache store as you can see in this version of the file :
https://github.com/rails/rails/blob/79d01a8f16e20c556a086a2f07e3ccb4400f9819/activesupport/lib/active_support/cache.rb#L577