Drew H
Drew H

Reputation: 4739

Caching ActiveRecord model instance methods

Say I have a user model. It has an instance method called status. Status is not an association. It doesn't follow any active record pattern because it's a database already in production.

class User < ActiveRecord::Base  

  def status
    Connection.where(machine_user_id: self.id).last
  end    

end

So I do this.

@users = User.all

First of all I can't eager load the status method.

@users.includes(:status).load

Second of all I can't cache that method within the array of users.

Rails.cache.write("user", @users)

The status method never gets called until the view layer it seems like.

What is the recommended way of caching this method.

Maybe this instance method is not what I want to do. I've looked at scope but it doesn't look like what I want to do.

Maybe I just need an association? Then I get the includes and I can cache.

But can associations handle complex logic. In this case the instance method is a simple query. What if I have complex logic in that instance method?

Thanks for any help.

Upvotes: 1

Views: 1163

Answers (1)

Edgars Jekabsons
Edgars Jekabsons

Reputation: 2853

Have You tried to encapsulate this logic inside some plain Ruby object like this (I wouldn't use this for very large sets though):

class UserStatuses
  def self.users_and_statuses
    Rails.cache.fetch "users_statuses", :expires_in => 30.minutes do
      User.all.inject({}) {|hsh, u| hsh[u.id] = u.status; hsh }
    end
  end
end

After that You can use some helper method to access cached version

class User < ActiverRecord::Base
  def cached_status
    UserStatuses.users_and_statuses[id]
  end
end

It doesn't solve Your eager loading problem, Rails doesn't have any cache warming up techniques built in. But by extracting like this, it's easily done by running rake task in Cron.

Also in this case I don't see any problems with using association. Rails associations allows You to submit different options including foreign and primary keys.

Upvotes: 1

Related Questions