【问题标题】:Override all queries to a given model in Rails 4在 Rails 4 中覆盖对给定模型的所有查询
【发布时间】:2013-11-30 07:16:39
【问题描述】:

是否可以在 Rails 中覆盖给定模型上的所有查询,而不管它们通过什么关联。示例:

我有一个Counties 模型,它被我的应用程序中的多个模型引用。一个Userbelongs to一个Country,一个Citybelongs to一个Country,等等。

因为Countries 表很少更改并且记录数量很少,所以我决定缓存整个内容,并且每当在应用程序中按 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.nameCity.country.name 等现有代码在Country 模型中处理以利用缓存值。

这可能吗?

更新

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

【问题讨论】:

  • 我很抱歉,但我刚刚意识到我并不真正了解缓存,而且我需要花更多的时间来理解它,而不是我现在愿意投入的时间。我很抱歉在没有足够知识的情况下回答。我已删除我的答案,希望其他人能回复。

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


【解决方案1】:

有点回答我自己的问题......我没有找到一种方法来做我想要的,但我所做的是在每个引用它的模型中覆盖 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多