Caching, ActiveRecord, and disappearing methods
I was very surprised to see that my model is missing some of its attributes after first request in development mode.
The error occurred while evaluating nil.include?
With the backtrace ending with:
/var/lib/gems/1.8/gems/activerecord-2.3.2/lib/active_record/attribute_methods.rb:142:in 'create_time_zone_conversion_attribute?'
Such a magic… ;-) Here is the recipe. Place in your controller:
def index
@posts = Rails.cache.fetch(:all_posts) { Post.all }
endGo to your view page and press refresh.
The reason is that ActiveRecord stores some information in so called class inheritable attributes. These are stored as your model class variable (Post in that case). Let’s see…
>> before_refresh = Post
>> before_refresh.object_id
=> 70091079977500
>> before_refresh.inheritable_attributes
=> {:skip_time_zone_conversion_for_attributes=>[], :record_timestamps=>true, :reject_new_nested_attributes_procs=>{}, :default_scoping=>[], :scopes=>{:scoped=>#<Proc:0x00007f7eb4450c10@/var/lib/gems/1.8/gems/activerecord-2.3.2/lib/active_record/named_scope.rb:87>}}
>> before_refresh.inheritable_attributes.object_id
=> 70091079977380
>> reload!
>> Post.object_id
=> 70091079300300 # different!
>> before_refresh.inheritable_attributes
=> {} # different!
>> before_refresh.inheritable_attributes.object_id
=> 70091099674080 # different! but similar ;-)It looks like ActiveRecord clears inheritable_attributes before reload… But why? I do not know… I am still learning ;-)
Anyway, here are some other reasons why you should not cache your models but described with the problem of requiring models.
If you still want to cache your models (why not?), here is the tip for disabling caching in your development mode (not so easy). You can set memcached as caching store and give it invalid port number. Queries will be missed all the time without any exception raised while writing to cache.
Edit:
Michał Kwiatkowski found better solution.
acts_as_list - null scope attribute value
Some time ago I ran into performance problems connected with acts_as_list.
My acts_as_list in EmailAddress model was defined as follows:
acts_as_list :scope => :userUnfortunately, most email addresses in database had user_id set to null.
Acts_as_list takes all records from table which has null scope attribute and creates one huge list from all of them… Ups… In my situation it means almost
SELECT * FROM email_addressesHere is my fix. It makes possible to write:
acts_as_list :scope => :user, :ignore_nil => trueAfter doing so, newly created EmailAddress will not be added to any list unless user is set to non null.
In my opinion original behaviour is quite odd as acts_as_list supports listable records which are not on any list…

My name is Kacper Bielecki. I am currently working at 