web-dev-qa-db-ja.com

Controllerのapplication.rbからconfigにアクセスする(Rails 3)

私はapplication.rbに2つの追加の構成オプションを追加して、コントローラーでそれらを読み取れるようにしようとしています。

# Extra
config.Twitter.key = 'foo'
config.Twitter.secret = 'bar'

私は3つの提案された方法を使用してそれらにアクセスしようとしています:

self.config.Twitter.key # Should be extended through ApplicationController Base
config.Twitter.key # Inherited but with different syntax
CONFIG['Twitter']['key'] #some massive magical array that apparently exists somewhere

これらはすべて、「デバッグ」メソッドを通過すると、さまざまな種類のエラーが発生します。例:

debug self.config.Twitter.key # undefined method `key' for nil:NilClass

どうしたの?

24
Phil Sturgeon

Config/application.rbに対する期待が何を提供しているかについて、少し間違った考えを持っていると思います。 ActiveRecord :: BaseおよびActiveController :: Base固有クラスは、config /application.rbで構成されているRails :: Application :: Configurationクラスを使用します。属性は、Baseクラスまたはそれらの固有クラスのいずれかから派生するクラスでは使用できません。これが、ApplicationControllerでエラーが発生する理由です。

Railsアプリで構成の初期化を行うには、通常2つの方法があります。最初の方法は、構成モジュールを作成し、初期化子を介してそれに値をロードすることです。

まず、TwiterConfigモジュールを作成します。

#lib/Twitter_config.rb
module TwitterConfig
  def self.config
    @@config ||= {}
  end

  def self.config=(hash)
    @@config = hash
  end
end

YAML構成ファイルを作成します。

# config/Twitter.yaml
development: &base
  key: "foo"
  secret: "bar"

test:
 <<: *base
 key: "foo2"

production:
  <<: *base
  secret: "barbar"

または、config/Twitter.yamlをSCMに追加する予定がない場合は、これをスキップして、環境変数を介してキーとシークレットを設定できます。これは、HerokuにデプロイされているパブリックSCMリポジトリを備えたアプリケーションに推奨されるソリューションです。

次に、初期化子を介して値をロードおよび設定します。

#config/initializers/01_Twitter.rb
require 'Twitter_config'

TwitterConfig.config = YAML.load_file("config/config.yml")[Rails.env].symbolize_keys

一般に、イニシャライザファイルにRailsはファイル名に従って順番にロードするため、番号を付けるのがベストプラクティスです。データストアを初期化していて、それが他のステップにとって重要である場合は、最小のファイルが必要ですまたは、環境変数を使用している場合、これはinitファイルになります。

#config/initializers/01_Twitter.rb
require 'Twitter_config'

TwitterConfig.config[:key] = ENV['Twitter_config_key']
TwitterConfig.config[:secret] = ENV['Twitter_config_secret']

Railsアプリケーション全体で、TwitterConfig.config [:key]とTwitterConfig.config [:secret]を使用して構成値にアクセスできるようになりました。モジュールを含めることもできます。注意してください。紛争のために。

値をグローバル定数としてロードすることもできます。しかし、それは私には少し醜い感じがします:

#config/application.rb
Twitter_CONFIG = YAML.load_file("config/Twitter.yaml")[Rails.env]
45

私はこれを試しましたが、機能しているようです。:: Rails.application.configを使用できます。

たとえば、次のようにアプリケーションで正しいtime_zoneセットを取得するために使用しています。

Rails.application.config.time_zone

Less-Railsコードのおかげで見つけました: https://github.com/metaskills/less-Rails/blob/master/lib/less/Rails/helpers.rb

したがって、これはapplication.rbまたは任意の環境ファイルで宣言できます。

config.Twitter_key = 'foo'

そして、コードのどこでもそのように読んでください:

Rails.application.config.Twitter_key

13
brutuscat

Yamlファイルアプローチの使用を検討することをお勧めします。

Application.rb内

CONFIG = YAML.load_file("config/config.yml")[Rails.env]

Config /config.yml内

development: &base_config
    Twitter_key = "foo"
    Twitter_secret = "bar"

test:
  <<: *base_config
    Twitter_key = "foo2"

production:
  <<: *base_config
    Twitter_secret = "barbar"

オーバーロードのある環境レベルで定義可能な属性を使用した以前と同じ使用法。

CONFIG['Twitter_key']
5
David Lyod

ここで広く受け入れられている答えへの小さな更新: Controller(Rails 3)のapplication.rbからconfigにアクセスする

モジュールTwitterConfig内のメソッドは、クラスメソッド(または、必要に応じてモジュールメソッド)である必要があります。インスタンスメソッドにすることはできません。

これを回答に入れて申し訳ありませんが、その回答にコメントする方法が見つかりませんでした。

0
brahmana