Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails.cache.fetch exception: TypeError (<ModelName> can't be referred to)

I'm implementing some caching by using the nifty Rails.cache.fetch. However, in one particular instance, sometimes I encounter an exception:

TypeError in EmloController#index

Emlo can't be referred to

app/controllers/emlo_controller.rb:320:in `get_employees'
app/controllers/emlo_controller.rb:356:in `prepare_json_response'
app/controllers/emlo_controller.rb:23:in `block (2 levels) in index'
app/controllers/emlo_controller.rb:15:in `index'

It seems the fetch will always explode (with the above) on the first try, and then work fine as long as the fetch is within the expiration. I know I'm missing something, so a fresh pair of eyes would be nice.

Here's the method which invokes the cache fetch:

def get_employees

  # This is for a AJAX refresh loop, so a 5-second cache actually helps quite a bit
  Rails.cache.fetch('emlo_all', :expires_in => 5.seconds, :race_condition_ttl => 1) do

    conditions = (params[:id]) ? {:user_id => params[:id]} : nil

    selections = [
      'employee_locations.id AS emlo_id',
      'employee_locations.status_id',
      'employee_locations.notes',
      'employee_locations.until',
      'employee_locations.updated_at',
      'employee_locations.user_id',
      'location_states.id AS state_id',
      'location_states.title AS status_string',
      'location_states.font_color',
      'location_states.bg_color',
      'users.displayname',
      'users.email',
      'users.mobile',
      'users.department',
      'users.extension',
      'users.guid',
      'users.dn'
    ].join(', ')

    Emlo.all(
        :select => selections,
        :joins => 'LEFT JOIN users ON employee_locations.user_id=users.id LEFT JOIN location_states ON employee_locations.status_id=location_states.id',
        :conditions => conditions,
        :order => 'users.displayname ASC'
    )
  end
end
like image 666
Matthew Clark Avatar asked Oct 05 '11 16:10

Matthew Clark


1 Answers

This problem arises in development mode when config.action_controller.perform_caching = true AND config.cache_classes = false -- it seems ActiveRecord objects cannot be stored with Rails.cache.

But if you need to enable config.action_controller.perform_caching in development mode for testing caching, then you must also enable config.cache_classes. This would be temporary, though, because then you'd have to restart the development server after changing classes or files in the asset pipeline.

With caching disabled, I would use Rails.cache.write(some_name, some_value) if Rails.env.production? to prevent caching from blowing up in development. Rails.cache.read() doesn't seem to be affected.

like image 55
Matthew Clark Avatar answered Nov 23 '22 23:11

Matthew Clark