Railsでconfig_forを使ったときのsymbolize_keysについてコンソールで確認してみる。
上の記事のとき、config_for
の後ろにyamlファイルの値を参照するとき、
シンボルで引っ張ってくるかどうするかみたいなときに、個人的にはシンボルで
引っ張ってあげたほうがわかりやすかった。
なんパターンかあるので、コンソールで確認してみる。
application.rbにどう書いてあるか
config.x.hogehoge = config_for(:test)
config.x.hogehoge = config_for(:test).symbolize_keys
-
config.x.hogehoge = config_for(:test).deep_symbolize_keys
-
config.x.hogehoge = ActiveSupport::InheritableOptions.new(Rails.application.config_for(:test))
config.x.preference
に格納した値をcontrollerで引っ張るときは、Rails.configuration.x.hogehoge
で引っ張る。
ちなみに、test.yml
の中身は以下。
default: &default hoge_k: hoge_v fuga_k: fuga_k_1: fuga_v_1 fuga_k_2: fuga_v_2 foo: - bar - baz development: <<: *default test: <<: *default production: <<: *default
1のとき
> test = Rails.application.config_for(:test) => {"hoge_k"=>"hoge_v", "fuga_k"=>{"fuga_k_1"=>"fuga_v_1", "fuga_k_2"=>"fuga_v_2"}, "foo"=>["bar", "baz"]} > test["hoge_k"] => "hoge_v" > test[:hoge_k] => nil > test.hoge_k NoMethodError: undefined method `hoge_k' for #<Hash:0x000000000567b3d0> from (irb):4
何もつけないときは、
controllerとかではRails.configuration.x.hogehoge["fuga_k"]["fuga_k_1"]
でfuga_v_2
が引っ張れる。
2のとき
symbolize_keys
のとき
> test = Rails.application.config_for(:test).symbolize_keys => {:hoge_k=>"hoge_v", :fuga_k=>{"fuga_k_1"=>"fuga_v_1", "fuga_k_2"=>"fuga_v_2"}, :foo=>["bar", "baz"]} > test["hoge_k"] => nil > test[:hoge_k] => "hoge_v" > test.hoge_k NoMethodError: undefined method `hoge_k' for #<Hash:0x00000000053315f8> from (irb):15 > test[:fuga_k] => {"fuga_k_1"=>"fuga_v_1", "fuga_k_2"=>"fuga_v_2"} > test[:fuga_k][:fuga_k_1] => nil
1階層目はシンボルで引っ張れるが、2階層以降は
Rails.configuration.x.hogehoge[:fuga_k]["fuga_k_1"]
のようにしないとひっぱれない。
3のとき
> test = Rails.application.config_for(:test).deep_symbolize_keys => {:hoge_k=>"hoge_v", :fuga_k=>{:fuga_k_1=>"fuga_v_1", :fuga_k_2=>"fuga_v_2"}, :foo=>["bar", "baz"]} > test[:fuga_k][:fuga_k_1] => "fuga_v_1"
これが一番いいのでは。
4のとき
> test = ActiveSupport::InheritableOptions.new(Rails.application.config_for(:test).deep_symbolize_keys) => {} > test.hoge_k => "hoge_v" > test.fuga_k.fuga_k_1 NoMethodError: undefined method `fuga_k_1' for {:fuga_k_1=>"fuga_v_1", :fuga_k_2=>"fuga_v_2"}:Hash from (irb):56 > test.fuga_k[:fuga_k_1] => "fuga_v_1" irb(main):059:0> test.fuga_k["fuga_k_1"] => nil
第一階層のみ.
で繋げるが、第二階層以降はシンボルで繋がないとだめみたい。。。
ActiveSupport::InheritableOptionsってなんぞや
ActiveSupport::InheritableOptions
はシンボルでなくて、.
で繋げる
> test = ActiveSupport::InheritableOptions.new({name: "Bob"}) => {} > test.name => "Bob"
既存のハッシュを.でつなげる。
ActiveSupport::InheritableOptions
は子クラスで、親クラスの
ActiveSupport::OrderedOptions
は新規に作るときにつかうやつ。
> test = ActiveSupport::OrderedOptions.new => {} > test[:name] = "Alice" => "Alice" > test.name => "Alice" > test = ActiveSupport::OrderedOptions.new => {} > test[:human] = {name: "Charlie"} => {:name=>"Charlie"} > test[:human][:name] => "Charlie" > test.human.name NoMethodError: undefined method `name' for {:name=>"Charlie"}:Hash from (irb):68 > test.human[:name] => "Charlie" > test = ActiveSupport::InheritableOptions.new({human: {name: "Bob"}}) => {} > test.human.name NoMethodError: undefined method `name' for {:name=>"Bob"}:Hash from (irb):41 > test.human[:name] => "Bob"
ソース見ても難しかったのでわからず。