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?

Ethan
sumber

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.

John Topley
sumber
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
David Burrows
sumber
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

Ali MasudianPour
sumber
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']
Omer Aslam
sumber
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

kotor
sumber
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.

Foomip
sumber
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'] %>
Jack Chu
sumber
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]

twmulloy
sumber
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)

Kitebuggy
sumber
0

Saya suka simpleconfig . Ini memungkinkan Anda untuk memiliki konfigurasi per lingkungan.

Jerry Cheung
sumber
0

lihat tanggapan saya terhadap Di mana tempat terbaik untuk menyimpan parameter aplikasi: database, file, kode ...?

Variasi untuk apa yang Anda miliki sebagai referensi sederhana ke file lain. Ia melihat bahwa environment.rb tidak selalu diperbarui dan tidak memiliki banyak hal khusus aplikasi di dalamnya. Meskipun bukan jawaban spesifik untuk pertanyaan Anda tentang 'apakah itu jalan Rails?', Mungkin akan ada beberapa diskusi di sana tentang itu.

Straff
sumber
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"]
6ft Dan
sumber
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

greenif
sumber
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
Marcelo Austria
sumber