在Rails 4中覆盖对给定模型的所有查询

时间:2013-11-19 23:30:29

标签: ruby-on-rails caching ruby-on-rails-4

在Rails中是否可以覆盖给定模型上的所有查询,无论它们通过何种关联。例如:

我有一个Counties模型,我的应用程序中有几个模型引用它。一个User belongs to一个Country,一个City belongs to一个Country,依此类推。

因为Countries表变化非常少而且记录数量很少,所以我决定缓存整个事情,每当在应用程序中查找Country by ID时,我希望它通过该缓存而不是查询数据库。

Country模型中的缓存代码如下所示:

after_save :expire_all
after_destroy :expire_all

def self.all_cached
 Rails.cache.fetch('Countries.all') { all }
end

def expire_all
  Rails.cache.delete('Countries.all')
end

现在,我想避免进入应用程序中的每个可能位置并更改逻辑以使用该缓存。

我正在寻找一种方法,以便在User.country.name模型中处理现有代码,例如City.country.nameCountry,以便使用缓存值。

这可能吗?

更新

在应用程序的其他位置,我将Country.where(:continent => 5) Country.where(:active => true)。我想在缓存的桌子而不是真正的桌子上查询所有这些。所以我想我正在寻找的是一种在模型中定义要在我的缓存对象而不是数据库上执行的所有查询的方法。

1 个答案:

答案 0 :(得分:0)

回答我自己的问题...我没有找到一种方法来完全按照我的意愿行事,但我所做的是在每个引用它的模型中覆盖Country getter方法以便它浏览缓存变量。

Country模型中的其他方法:

  def self.cached_coutry(id)
    all_cached.each do |country|
      return country if (country.id == id)
    end   
  end

在相关模型中{UserCity等):

class User
  belongs_to :country
  def country
    Country.cached_country(country_id)
  end
end

关于Heroku上memcache性能的旁注。 我在Heroku上使用Memcachier插件在免费计划中托管该网站。在实现此解决方案之后,我没有注意到性能的提高,因为对缓存的调用花费的时间与在数据库上执行此简单国家/地区查找所需的时间相似。因此,为了挤出更多的性能,我决定将Countries的整个列表存储在类变量中:

def self.all_cached
  @@all_countries ||= Country.all
end

def expire_all
  @@all_countries = nil
end