Setting the cache_store in an initializer

2019-01-14 02:57发布

I'm trying to use redis-store as my Rails 3 cache_store. I also have an initializer/app_config.rb which loads a yaml file for config settings. In my initializer/redis.rb I have:

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

However, this doesn't appear to work. If I do:

Rails.cache

in my rails console I can clearly see it's using the

ActiveSupport.Cache.FileStore

as the cache store instead of redis-store. However, if I add the config in my application.rb file like this:

config.cache_store = :redis_store 

it works just fine, except the app config initializer is loaded after application.rb, so I don't have access to APP_CONFIG.

Has anyone experienced this? I can't seem to set a cache store in an initializer.

6条回答
Summer. ? 凉城
2楼-- · 2019-01-14 03:02

Had the same problem and setting RAILS_CACHE to MyApp::Application.config.cache_store fixed it as well.

查看更多
孤傲高冷的网名
3楼-- · 2019-01-14 03:03

I tried the following and it works out.

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楼-- · 2019-01-14 03:05

In the original setup you had, does it help if you change:

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

to:

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

?

查看更多
放荡不羁爱自由
5楼-- · 2019-01-14 03:07

After some research, a probable explanation is that the initialize_cache initializer is run way before the rails/initializers are. So if it's not defined earlier in the execution chain then the cache store wont be set. You have to configure it earlier in the chain, like in application.rb or environments/production.rb

My solution was to move the APP_CONFIG loading before the app gets configured like this:

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

and then in the same file:

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

Another option was to put the cache_store in a before_configuration block, something like this:

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
查看更多
Fickle 薄情
6楼-- · 2019-01-14 03:23

The config/initializers are run after the Rails.cache is initialized, but after config/application.rb and config/environments.

Configuration in config/application.rb or environments

Thus, one solution would be to configure the cache in config/application.rb or config/environments/*.rb.

Configuration in config/initializers/cache.rb

If the cache should be configured in an initializer intentionally, this can be done by setting Rails.cache manually after the configuration:

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

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

Add a spec

In order to make sure it worked, add a spec like this:

# 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

Further information

查看更多
甜甜的少女心
7楼-- · 2019-01-14 03:23

In the initializer

REDIS ||= Rails.configuration.redis_client

In 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 }
查看更多
登录 后发表回答