Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Cache Key generated as ActiveRecord::Relation

I am attempting to generate a fragment cache (using a Dalli/Memcached store) however the key is being generated with "#" as part of the key, so Rails doesn't seem to be recognizing that there is a cache value and is hitting the database.

My cache key in the view looks like this:

cache([@jobs, "index"]) do

The controller has:

@jobs = @current_tenant.active_jobs

With the actual Active Record query like this:

def active_jobs
   self.jobs.where("published = ? and expiration_date >= ?", true, Date.today).order("(featured and created_at > now() - interval '" + self.pinned_time_limit.to_s + " days') desc nulls last, created_at desc")
end

Looking at the rails server, I see the cache read, but the SQL Query still runs:

Cache read: views/#<ActiveRecord::Relation:0x007fbabef9cd58>/1-index 
Read fragment views/#<ActiveRecord::Relation:0x007fbabef9cd58>/1-index (1.0ms)
(0.6ms) SELECT COUNT(*) FROM "jobs" WHERE "jobs"."tenant_id" = 1 AND (published = 't' and expiration_date >= '2013-03-03')
  Job Load (1.2ms)  SELECT "jobs".* FROM "jobs" WHERE "jobs"."tenant_id" = 1 AND (published = 't' and expiration_date >= '2013-03-03') ORDER BY (featured and created_at > now() - interval '7 days') desc nulls last, created_at desc

Any ideas as to what I might be doing wrong? I'm sure it has to do w/ the key generation and ActiveRecord::Relation, but i'm not sure how.

like image 213
cman77 Avatar asked Dec 04 '22 12:12

cman77


1 Answers

Background:

The problem is that the string representation of the relation is different each time your code is run:

                                 |This changes| 
views/#<ActiveRecord::Relation:0x007fbabef9cd58>/...

So you get a different cache key each time.

Besides that it is not possible to get rid of database queries completely. (Your own answer is the best one can do)

Solution:

To generate a valid key, instead of this

cache([@jobs, "index"])

do this:

cache([@jobs.to_a, "index"])

This queries the database and builds an array of the models, from which the cache_key is retrieved.

PS: I could swear using relations worked in previous versions of Rails...

like image 90
Daniel Rikowski Avatar answered Dec 07 '22 01:12

Daniel Rikowski