Setting the cache_store in an initializer

前端 未结 6 814
一向
一向 2020-12-05 10:38

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

相关标签:
6条回答
  • 2020-12-05 11:14

    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)
    
    0 讨论(0)
  • 2020-12-05 11:14

    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
    

    ?

    0 讨论(0)
  • 2020-12-05 11:20

    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

    • Rails.cache is set here during the application bootstrap: https://github.com/rails/rails/blob/5-0-stable/railties/lib/rails/application/bootstrap.rb#L62L70. The redis store does not respond to :middleware. Thus, we can leave out the additional lines.
    • See also: https://github.com/rails/rails/issues/10908#issuecomment-19281765
    • http://guides.rubyonrails.org/caching_with_rails.html#cache-stores
    0 讨论(0)
  • 2020-12-05 11:21

    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
    
    0 讨论(0)
  • 2020-12-05 11: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 }
    
    0 讨论(0)
  • 2020-12-05 11:29

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

    0 讨论(0)
提交回复
热议问题