缓存ActiveRecord模型实例方法

时间:2013-10-09 19:12:42

标签: ruby ruby-on-rails-4

说我有一个用户模型。它有一个名为status的实例方法。状态不是关联。它不遵循任何活动记录模式,因为它是一个已经在生产中的数据库。

class User < ActiveRecord::Base  

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

end

所以我这样做。

@users = User.all

首先,我不能急于加载状态方法。

@users.includes(:status).load

其次,我无法在用户数组中缓存该方法。

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

在看起来像视图层之前,状态方法永远不会被调用。

缓存此方法的推荐方法是什么。

也许这个实例方法不是我想做的。我看过范围,但看起来不像我想做的那样。

也许我只需要一个关联?然后我得到了包含,我可以缓存。

但协会可以处理复杂的逻辑。在这种情况下,实例方法是一个简单的查询。如果我在该实例方法中有复杂的逻辑怎么办?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

你有没有试过将这个逻辑封装在像这样的普通Ruby对象中(虽然我不会将它用于非常大的集合):

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

之后您可以使用一些帮助方法来访问缓存版本

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

它没有解决你急切的加载问题,Rails没有内置任何缓存预热技术。但通过这样提取,可以通过在Cron中运行rake任务轻松完成。

同样在这种情况下,我发现使用关联没有任何问题。 Rails关联允许您提交不同的选项,包括外键和主键。