Cara terbaik untuk membuat opsi konfigurasi khusus untuk aplikasi Rails saya?


133

Saya perlu membuat satu opsi konfigurasi untuk aplikasi Rails saya. Ini bisa sama untuk semua lingkungan. Saya menemukan bahwa jika saya mengaturnya environment.rb, itu tersedia dalam pandangan saya, yang persis seperti yang saya inginkan ...

environment.rb

AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

Bagus sekali.

Namun, saya sedikit gelisah. Apakah ini cara yang baik untuk melakukannya? Apakah ada cara yang lebih modern?

Jawaban:


191

Untuk konfigurasi aplikasi umum yang tidak perlu disimpan dalam tabel database, saya ingin membuat config.ymlfile di dalam direktori config . Sebagai contoh Anda, ini mungkin terlihat seperti ini:

defaults: &defaults
  audiocast_uri_format: http://blablalba/blabbitybla/yadda

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

File konfigurasi ini diambil dari penginisialisasi khusus di config / initializers :

# Rails 2
APP_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/config.yml")[RAILS_ENV]

# Rails 3+
APP_CONFIG = YAML.load_file(Rails.root.join('config/config.yml'))[Rails.env]

Jika Anda menggunakan Rails 3, pastikan Anda tidak secara tidak sengaja menambahkan garis miring terkemuka ke jalur konfigurasi relatif Anda.

Anda kemudian dapat mengambil nilai menggunakan:

uri_format = APP_CONFIG['audiocast_uri_format']

Lihat Railscast ini untuk detail selengkapnya.


1
Anda mungkin perlu YAML::ENGINE.yamler = 'syck'ini untuk bekerja stackoverflow.com/a/6140900/414220
evanrmurphy

45
Hanya FYI, di Rails 3.x Anda harus mengganti RAILS_ENVdengan Rails.envdan RAILS_ROOTdengan Rails.root.
JeanMertz

5
Untuk Rails 3+ Anda harus bergabung dengan jalur relatif, bukan absolut. Jangan awali direktori konfigurasi dengan slash.
wst

10
Tidak yakin tentang versi sebelumnya tetapi dalam Rails 4.1 yang dapat Anda lakukanRails.application.config.whatever_you_want = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
d4rky

2
@ iphone007 memang mungkin untuk memuat file yaml yang sewenang-wenang dari direktori config. lihat jawaban smathy di bawah ini yang menurut saya sekarang harus menjadi jawaban yang diterima.
omnikron

82

Versi Rails 3 kode initialiser adalah sebagai berikut (RAILS_ROOT & RAILS_ENV tidak digunakan lagi)

APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]

Selain itu, Ruby 1.9.3 menggunakan Psikologi yang membuat menggabungkan huruf besar-kecil sehingga Anda perlu mengubah file konfigurasi Anda untuk memperhitungkannya, misalnya

defaults: &DEFAULTS
  audiocast_uri_format: http://blablalba/blabbitybla/yadda

development:
  <<: *DEFAULTS

test:
  <<: *DEFAULTS

production:
  <<: *DEFAULTS

3
Anda tidak perlu "#{Rails.root.to_s}"; "#{Rails.root}"bekerja.
David J.

3
Saya sarankan Rails.root.join('config', 'config.yml')daripada"#{Rails.root.to_s}/config/config.yml"
David J.

2
Dan, alih-alih APP_CONFIG, saya sarankan menggunakan:AppName::Application.config.custom
David J.

1
David, dua komentar pertama Anda adalah praktik terbaik dan saya akan mengubah kode tetapi yang terakhir saya akan tinggalkan karena ini berarti Anda harus ingat untuk mengubah AppName setiap kali Anda menggunakan kode ini.
David Burrows

53

Rails> = 4.2

Hanya membuat YAMLfile ke config/direktori, misalnya: config/neo4j.yml.

Konten neo4j.ymldapat berupa sesuatu seperti di bawah ini (Untuk kesederhanaan, saya menggunakan default untuk semua lingkungan):

default: &default
  host: localhost
  port: 7474
  username: neo4j
  password: root

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

di config/application.rb:

module MyApp
  class Application < Rails::Application
    config.neo4j = config_for(:neo4j)
  end
end

Sekarang, konfigurasi khusus Anda dapat diakses seperti di bawah ini:

Rails.configuration.neo4j['host'] #=>localhost
Rails.configuration.neo4j['port'] #=>7474

Info lebih lanjut

Dokumen API resmi Rails menjelaskan config_formetode sebagai:

Kenyamanan untuk memuat config / foo.yml untuk Rails saat ini env.


Jika Anda tidak ingin menggunakan yamlfile

Seperti yang dikatakan panduan resmi Rails:

Anda dapat mengonfigurasi kode Anda sendiri melalui objek konfigurasi Rails dengan konfigurasi khusus di bawah config.xproperti.

Contoh

config.x.payment_processing.schedule = :daily
config.x.payment_processing.retries  = 3
config.x.super_debugger = true

Titik-titik konfigurasi ini kemudian tersedia melalui objek konfigurasi:

Rails.configuration.x.payment_processing.schedule # => :daily
Rails.configuration.x.payment_processing.retries  # => 3
Rails.configuration.x.super_debugger              # => true
Rails.configuration.x.super_debugger.not_set      # => nil

Referensi Resmi untuk config_formetode | Panduan Rel Resmi


25

Langkah 1: Buat config / initializers / appconfig.rb

require 'ostruct'
require 'yaml'

all_config = YAML.load_file("#{Rails.root}/config/config.yml") || {}
env_config = all_config[Rails.env] || {}
AppConfig = OpenStruct.new(env_config)

Langkah 2: Buat config / config.yml

common: &common
  facebook:
    key: 'asdjhasxas'
    secret : 'xyz'
  twitter:
    key: 'asdjhasxas'
    secret : 'abx'

development:
  <<: *common

test:
  <<: *common

production:
  <<: *common

Langkah 3: Dapatkan konstanta di mana saja dalam kode

facebook_key = AppConfig.facebook['key']
twitter_key  = AppConfig.twitter['key']

Bagaimana kita membaca variabel ENV di config.yml, konfigurasi saya sama .. saya telah menambahkan variabel di bashrc dan saya mencoba membaca itu di config.yml menggunakan kunci: <% = ENV [URL]%> ... this tidak bekerja
shiva

@shiva Lihatlah ke permata Figaro untuk variabel ENV. Konfigurasi konfigurasi ini adalah untuk nilai-nilai yang tidak perlu disembunyikan dari kontrol sumber.
Shadoath

17

Saya hanya ingin memperbarui ini untuk hal-hal keren terbaru di Rails 4.2 dan 5, sekarang Anda dapat melakukan ini di dalam salah satu config/**/*.rbfile Anda :

config.x.whatever = 42

(dan itu literal xdi sana, mis. yang config.x.harfiah harus itu, dan kemudian Anda dapat menambahkan apa pun yang Anda inginkan setelahx )

... dan ini akan tersedia di aplikasi Anda sebagai:

Rails.configuration.x.whatever

Lihat lebih lanjut di sini: http://guides.rubyonrails.org/configuring.html#custom-configuration


3
Hanya klarifikasi yang awalnya menyebabkan masalah bagi saya; x bukan pengganti untuk apa pun yang Anda ingin masukkan, itu benar-benar perlu surat itu x.
tobinibot

Poin bagus @tobinibot - Saya telah menambahkan klarifikasi itu ke jawaban saya, terima kasih.
smathy

Menarik bahwa panduan sebenarnya tidak menyebutkan 'x', tetapi saya dapat membuktikan bahwa masih diperlukan pada Rails 5.0
Don

Anda benar Don, itu aneh - saya yakin itu dulu.
apatis

1
Dari dokumen rails saat ini: You can configure your own code through the Rails configuration object with custom configuration under either the config.x namespace, or config directly. The key difference between these two is that you should be using config.x if you are defining nested configuration (ex: config.x.nested.nested.hi), and just config for single level configuration (ex: config.hello).Sumber: guides.rubyonrails.org/configuring.html#custom-configuration
David Gay

6

Hanya beberapa info tambahan tentang topik ini:

APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env].with_indifferent_access

".with_indifferent_access" memungkinkan Anda untuk mengakses nilai-nilai dalam hash menggunakan kunci string atau dengan kunci simbol yang setara.

misalnya.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'

Benar-benar hal yang mudah, tetapi saya lebih suka kunci saya direpresentasikan sebagai simbol.


5

Saya menggunakan sesuatu yang mirip dengan John for Rails 3.0 / 3.1, tapi saya harus parsing file terlebih dahulu:

APP_CONFIG = YAML.load(ERB.new(File.new(File.expand_path('../config.yml', __FILE__)).read).result)[Rails.env]

Ini memungkinkan saya untuk menggunakan ERB dalam konfigurasi saya jika perlu, seperti membaca url redistogo heroku:

production:
  <<: *default
  redis:                  <%= ENV['REDISTOGO_URL'] %>

2
Saya tidak berpikir saya akan membutuhkan ini setiap hari, tetapi ini adalah solusi yang sangat keren untuk saat-saat ketika Anda membutuhkannya. Saya pikir saya akan mengubah nama file menjadi config.yml.erb meskipun untuk mencocokkan konvensi rel.
Andrew Burns

2

Rails 4

Untuk membuat yaml konfigurasi khusus dan memuatnya (dan membuatnya tersedia untuk aplikasi Anda) mirip dengan caranya database_configuration .

Buat Anda *.yml, dalam kasus saya, saya memerlukan file konfigurasi redis.

config/redis.yml

default: &default
  host: localhost
  port: 6379

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default
  host: <%= ENV['ELASTICACHE_HOST'] %>
  port: <%= ENV['ELASTICACHE_PORT'] %>

Kemudian muat konfigurasi

config/application.rb

module MyApp
  class Application < Rails::Application

    ## http://guides.rubyonrails.org/configuring.html#initialization-events
    config.before_initialize do
      Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")
    end

  end
end

Akses nilai-nilai:

Rails.configuration.redis_configuration[Rails.env]mirip dengan bagaimana Anda dapat memiliki akses ke database.ymloleh AndaRails.configuration.database_configuration[Rails.env]


Anda juga bisa menyelamatkan diri beberapa waktu dengan hanya mengambil setting untuk lingkungan Anda saat ini, yang mungkin satu-satunya yang Anda perlu pula: Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]. Namun dalam kereta 4.2 dan di atas jawaban smathy mungkin cara yang lebih mudah untuk pergi.
omnikron

1

Membangun solusi elegan Omer Aslam, saya memutuskan untuk mengubah kunci menjadi simbol. Satu-satunya perubahan adalah:

all_config = YAML.load_file("#{Rails.root}/config/config.yml").with_indifferent_access || {}

Ini memungkinkan Anda untuk kemudian merujuk nilai dengan simbol sebagai kunci, misalnya

AppConfig[:twitter][:key]

Ini terlihat lebih rapi di mataku.

(Diposting sebagai jawaban karena reputasi saya tidak cukup tinggi untuk mengomentari balasan Omer)




0

Saya lebih suka mengakses pengaturan melalui tumpukan aplikasi global. Saya menghindari kelebihan variabel global dalam lingkup lokal.

config / initializers / myconfig.rb

MyAppName::Application.define_singleton_method("myconfig") {YAML.load_file("#{Rails.root}/config/myconfig.yml") || {}}

Dan akses dengan.

MyAppName::Application.myconfig["yamlstuff"]

0

Cara saya memuat Pengaturan sebelum Rail diinisialisasi

Memungkinkan Anda menggunakan pengaturan dalam inisialisasi Rails dan mengonfigurasi pengaturan per lingkungan

# config/application.rb
Bundler.require(*Rails.groups)

mode = ENV['RAILS_ENV'] || 'development'
file = File.dirname(__FILE__).concat('/settings.yml')
Settings = YAML.load_file(file).fetch(mode)
Settings.define_singleton_method(:method_missing) {|name| self.fetch(name.to_s, nil)}

Anda bisa mendapatkan pengaturan dengan dua cara: Pengaturan ['email'] atau Settings.email


0

Cara terbaik saya untuk konfigurasi kustom, dengan memunculkan pesan ketika setting.yml tidak ada.

akan dimuat dari penginisialisasi kustom di config / initializers / custom_config.rb

setting_config = File.join(Rails.root,'config','setting.yml')
raise "#{setting_config} is missing!" unless File.exists? setting_config
config = YAML.load_file(setting_config)[Rails.env].symbolize_keys

@APP_ID = config[:app_id]
@APP_SECRET = config[:app_secret]

Buat YAML di config / setting.yml

development:
  app_id: 433387212345678
  app_secret: f43df96fc4f65904083b679412345678

test:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212

production:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.