在初始化程序中设置 cache_store

Posted

技术标签:

【中文标题】在初始化程序中设置 cache_store【英文标题】:Setting the cache_store in an initializer 【发布时间】:2011-08-14 04:41:22 【问题描述】:

我正在尝试使用redis-store 作为我的 Rails 3 cache_store。我还有一个初始化程序/app_config.rb,它加载一个用于配置设置的 yaml 文件。在我的初始化程序/redis.rb 我有:

MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis'] 

但是,这似乎不起作用。如果我这样做:

Rails.cache

在我的 Rails 控制台中,我可以清楚地看到它正在使用

ActiveSupport.Cache.FileStore

作为缓存存储而不是 redis-store。但是,如果我像这样在 application.rb 文件中添加配置:

config.cache_store = :redis_store 

它工作得很好,除了应用程序配置初始化程序是在 application.rb 之后加载的,所以我无权访问 APP_CONFIG。

有人经历过吗?我似乎无法在初始化程序中设置缓存存储。

【问题讨论】:

github.com/rails/rails/issues/10908 与此处相关。如下所述,问题在于缓存在 Rails 启动过程的早期初始化,以便其他 Rail tie 可以使用它。 【参考方案1】:

在some research 之后,可能的解释是initialize_cache 初始化程序在rails/initializers 之前运行。因此,如果它没有在执行链的早期定义,那么缓存存储将不会被设置。您必须在链的早期配置它,例如在 application.rb 或 environment/production.rb

我的解决方案是在应用配置之前移动 APP_CONFIG 加载:

APP_CONFIG = YAML.load_file(File.expand_path('../config.yml', __FILE__))[Rails.env]

然后在同一个文件中:

config.cache_store = :redis_store, APP_CONFIG['redis']

另一种选择是将 cache_store 放在 before_configuration 块中,如下所示:

config.before_configuration do
  APP_CONFIG = YAML.load_file(File.expand_path('../config.yml', __FILE__))[Rails.env]
  config.cache_store = :redis_store, APP_CONFIG['redis']
end

【讨论】:

【参考方案2】:

config/initializersRails.cache 初始化之后运行,但在config/application.rbconfig/environments 之后运行。

config/application.rb 或环境中的配置

因此,一种解决方案是在config/application.rbconfig/environments/*.rb 中配置缓存。

config/initializers/cache.rb 中的配置

如果有意在初始化程序中配置缓存,可以在配置后手动设置Rails.cache

# config/initializers/cache.rb
Rails.application.config.cache_store = :redis_store, APP_CONFIG['redis']

# Make sure to add this line (http://***.com/a/38619281/2066546):
Rails.cache = ActiveSupport::Cache.lookup_store(Rails.application.config.cache_store)

添加规范

为了确保它有效,请添加如下规范:

# spec/features/smoke_spec.rb
require 'spec_helper'

feature "Smoke test" do
  scenario "Testing the rails cache" do
    Rails.cache.write "foo", "bar"
    expect(Rails.cache.read("foo")).to eq "bar"
    expect(Rails.cache).to be_kind_of ActiveSupport::Cache::RedisStore
  end
end

更多信息

Rails.cache 在应用程序引导期间在此处设置:https://github.com/rails/rails/blob/5-0-stable/railties/lib/rails/application/bootstrap.rb#L62L70。 redis store 没有回复:middleware。因此,我们可以省略额外的行。 另见:https://github.com/rails/rails/issues/10908#issuecomment-19281765 http://guides.rubyonrails.org/caching_with_rails.html#cache-stores

【讨论】:

虽然老了,但我可以确认在 Rails 5 中 Rails.cache = ActiveSupport::Cache.lookup_store(store_name) 行是我需要的秘密。【参考方案3】:

我尝试了以下方法,它成功了。

MyApp::Application.config.cache_store = :redis_store
self.class.send :remove_const, :RAILS_CACHE if self.class.const_defined? :RAILS_CACHE
RAILS_CACHE = ActiveSupport::Cache.lookup_store(MyApp::Application.config.cache_store)

【讨论】:

【参考方案4】:

在你原来的设置中,如果你改变它有帮助吗:

MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis'] 

到:

MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis'] 
RAILS_CACHE = MyApp::Application.config.cache_store

?

【讨论】:

这可行,但给出:警告:已初始化常量 RAILS_CACHE。【参考方案5】:

遇到同样的问题,将RAILS_CACHE 设置为MyApp::Application.config.cache_store 也解决了问题。

【讨论】:

【参考方案6】:

在初始化器中

REDIS ||= Rails.configuration.redis_client

在 application.rb 中

config.redis_client = Redis.new(
  :host => ENV["REDIS_HOST"], 
  :port => ENV["REDIS_PORT"],
  :db => ENV["REDIS_DB"].to_i,
)

config.cache_store = :redis_store,  client: config.redis_client 

【讨论】:

以上是关于在初始化程序中设置 cache_store的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 应用程序中设置初始焦点

如何在 Mac 应用程序中设置初始 Core Data 存储?

在 QSplitter PyQt 应用程序中设置 QTabWidget 的初始大小

如何在 Vuex 2 中设置初始状态?

你能在 Silverlight 的 SaveFileDialog 中设置初始目录吗

在 AppDelegate 中设置初始视图控制器时完全黑屏