Rails load YAML to hash and reference by symbol

前端 未结 11 2046
慢半拍i
慢半拍i 2021-02-01 12:22

I am loading a YAML file in Rails 3.0.9 like this:

APP_CONFIG = YAML.load(File.read(File.expand_path(\'../app.yml\', __FILE__)))

It loads the a

相关标签:
11条回答
  • 2021-02-01 12:24

    Try using the HashWithIndifferentAccess like

    APP_CONFIG = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../app.yml', __FILE__))))
    
    0 讨论(0)
  • 2021-02-01 12:26

    There is another potential answer I discovered while digging around.

    You can forgo HashWithIndifferentAccess.new by instead adding this to the top of your YAML files:

    --- !map:HashWithIndifferentAccess
    

    then simply YAML.load like normal. The only trick is that rails needs to already be loaded if you are doing this in your environment for use in initializers, etc. (like I am).

    0 讨论(0)
  • 2021-02-01 12:32
    1. Rails has a special method to symbolize keys.
    2. You can use load_file method and get rid of File.read
    3. Not sure if you need expand_path also, the default directory is rails root.

    I'd write it that simple:

    YAML::load_file('app.yml').symbolize_keys

    0 讨论(0)
  • 2021-02-01 12:35

    An alternative solution is to have the keys which you wish to access as a symbol prepended with a colon. For example:

    default: &default
      :symbol: "Accessed via a symbol only"
      string: "Accessed via a string only"
    
    development:
      <<: *default
    
    test:
      <<: *default
    
    production:
      <<: *default
    

    Later you can then access these like so:

    APP_CONFIG[:symbol]
    APP_CONFIG['string']
    

    Note that I am using YAML::ENGINE.yamler = "syck". Not sure if this works with psych. (Psych definitely won't support key merging as I showed in the example though.)

    About using HashWithIndifferentAccess: using it has the side effect of creating duplicate keys: one for symbol access and one for string access. This might be nefarious if you pass around YAML data as arrays. Be aware of this if you go with that solution.

    0 讨论(0)
  • 2021-02-01 12:35

    If you are working in Ruby on Rails, You might want to take a look at symbolize_keys(), which does exactly what the OP asked for. If the hash is deep,you can use deep_symbolize_keys(). Using this approach, the answer is

    APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__))).deep_symbolize_keys
    
    0 讨论(0)
  • 2021-02-01 12:35

    You are probably used to the params hash in Rails, which is actually a HashWithIndifferentAccess rather than a standard ruby Hash object. This allows you to use either strings like 'action' or symbols like :action to access the contents.

    With a HashWithIndifferentAccess, you will get the same results regardless of what you use, but keep in mind this only works on HashWithIndifferentAccess objects.

    So to make this work with YAML, you'll have to load the result of YAML.load into a HashWithIndifferentAccess, like so:

    APP_CONFIG = HashWithIndifferentAccess.new(   YAML.load(File.read(File.expand_path('../app.yml', __FILE__)))   )
    
    0 讨论(0)
提交回复
热议问题