在初始化程序中设置 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/initializers
在Rails.cache
初始化之后运行,但在config/application.rb
和config/environments
之后运行。
config/application.rb 或环境中的配置
因此,一种解决方案是在config/application.rb
或config/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的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Mac 应用程序中设置初始 Core Data 存储?
在 QSplitter PyQt 应用程序中设置 QTabWidget 的初始大小