开发者

Better way to organize Rails initializers

in my current Rails project I ended 开发者_如何学Goup with a lot of environment-specific initializers, for example my carrierwave.rb:

For development I use something like:

CarrierWave.configure do |config|
  config.cache_dir = Rails.root.join('tmp', 'carrierwave')
  config.storage = :file
end

For production I use S3 through fog:

CarrierWave.configure do |config|
  config.cache_dir = Rails.root.join('tmp', 'carrierwave')
  config.storage = :fog

  config.fog_public  = false
  config.fog_credentials = {
    provider:              'AWS',
    aws_access_key_id:     '...',
    aws_secret_access_key: '...'  
  }
end

I don't want to use lots of Rails.env.development? calls to switch between the configs, and I don't want to store this initializers inside my environment/*.rb files. Is there a way, for example to create a directory for each of my environments under the initializers directory?

initializers
├── development
│   └── carrierwave.rb
├── production
│   └── carrierwave.rb
└── test
    └── carrierwave.rb

The problem according to the Rails guides is following:

You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the initializers folder on down.


Put your environment specific initializers under /config/environments/initializers/[env] for example /config/environments/initializers/development and add something like this to config/application.rb:

module YourApp
  class Application < Rails::Application
    # Load environment specific initializers from "config/environments/initializers/[current_env]".
    initializer 'load_environment_initializers', after: :load_config_initializers do |app|
      Dir[File.join(File.dirname(__FILE__), 'environments', 'initializers', Rails.env.to_s, '**', '*.rb')].each {|file| require file }
    end

    ...

 end
end

It will require (load) all files from /config/environments/initializers/[env] and its subdirectories just after it has finished loading all regular initializers.


You'll have to move into into another directory mate, everything in the initializers folder will get included at boot time.

If you put the above instead into say..

rails_root/config/env_init_files/development

rails_root/config/env_init_files/production

Then you could do something like this..

#at the end of your environment.rb        
Dir["#{Rails.root}/config/env_init_files/#{Rails.env}/**/*"].each { |initializer| require initializer }


You can use dotenv gem and use environment variables to change the config across environemnts.


I have a Capistrano recipe that does this. Credentials are stored outside the repo (in a folder called /var/secure/) and are symlinked into config/initializers/ on deployment.

namespace :local do
  desc "Symlink all files in /var/secure into config/initializers.  This is how we get production keys into our apps without hard-coding them.  If they're production-only, great.  If there are development and production credentials, put the development credentials in the repo, and they will be overwritten during deploy."
  task :symlink_secure_initializers, :roles => [:app,:api] do
    run "for l in `ls /var/secure/*.rb`; do 
           rm -f #{release_path}/config/initializers/$(basename $l)
           ln -s /var/secure/$(basename $l) #{release_path}/config/initializers/$(basename $l)
         done"
  end
end

after "deploy:update_code", "local:symlink_secure_initializers"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜