There is a yaml file in a Rails application which named 'notices.yml'.
notices:
content: "Notice 1."
Now want to set the notice content to dynamatic as:
content: "Notice 1. Good"
So should parse parameter to it in some logic.
I have thought about Rails' I18n. If use something like I18n.t("notices.content", "Good") may realize it. The yaml should be:
notices:
content: "Notice 1. %{data}"
But how to make the method? I am using a way to read yaml file like:
# config/application.rb
config.notices = YAML.load_file("#{Rails.root}/config/notices.yml")
# Some controller
content = Rails.configuration.notices['notices']['content']
It seems difficult to set parameter like that way.
I checked the I18n's translate method:
https://github.com/ruby-i18n/i18n/blob/master/lib/i18n.rb#L179
It use **options to set data. I have no idea to make a simple way to realize this case.
I have an environment variable along the lines of:
MY_VALUE: "EFINbA\u003d\u003d\n"
When I read it through ruby it is returned as:
ENV['MY_VALUE']
=> "EFINbA\\u003d\\u003d\\n"
... but only on Heroku, not on Mac (where it was set through a local_env.yml file, admittedly)
So first of all, I just don't understand why it is doing that.
Secondly, when I attempt to remove the \ and replace them with \, I have found nothing that works.
Although:
ENV['MY_VALUE'].gsub("\","x")
=> "EFINbAxu003dxu003dxn"
This:
ENV['MY_VALUE'].gsub("\","\")
... doesn't work because the last double-quote is escaped, while:
ENV['MY_VALUE'].gsub("\\","\\")
... effectively does nothing at all.
Evidently I am missing something basic here, and it's too late in the day for me to spot it.
Thanks.
You can try YAML's unescape
require 'yaml'
def unescape(s)
YAML.load(%Q(---\n"#{s}"\n))
end
unescape(ENV['MY_VALUE'])
or if you don't bring in the yaml module you can use eval
def unescape(s)
eval %Q{"#{s}"}
end
The advantage to YAML over eval is that it is presumably safer.
YAML.safe_load sometimes changes characters in the env string - so it is not an optimal solution.
As eval is also not the solution as it is not that safe, .undump was the answer I was looking for.
I want to do something like this in console:
= raw CSV.generate_line(array)
And see how the output looks like.
The reason being the CSV output on Heroku is adding in extra newlines in every CSV file genrated and I can't replicate this on development. It's not very good practice to try random attempts to fix the problem by deployment =)
If anyone has hints to what might be causing the newline characters, be grateful too.
You can do it like this
engine = Haml::Engine.new("%p Haml code!")
engine.render #=> "<p>Haml code!</p>\n"
Of course you need to have haml gem required in your app but i assume you have this.
You can also have
include ActionView::Helpers
in your console.
and have raw, link_to and other helpers handy.
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 all of the contents like hierarchical hashes, no problem. The part I don't like is the fact that the hashes can only be accessed with single or double quotes but not a symbol.
APP_CONFIG['mailer']['username'] # works fine
APP_CONFIG[:mailer][:username] # doesn't
Any thoughts?
Try using the HashWithIndifferentAccess like
APP_CONFIG = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../app.yml', __FILE__))))
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.
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
Psych (a.k.a. YAML) provides the keyword argument :symbolize_names to load keys as symbols. See method reference
file_path = File.expand_path('../app.yml', __FILE__)
yaml_contents = File.read(file_path)
APP_CONFIG = YAML.safe_load(yaml_contents, symbolize_names: true)
This is the same from the selected answer, but with a better syntax:
YAML.load(File.read(file_path)).with_indifferent_access
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).
Rails has a special method to symbolize keys.
You can use load_file method and get rid of File.read
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
Just use appropriate option in your YAML parser. For instance, symbolize_names in Psych:
APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__)), symbolize_names: true)
See RDoc: https://ruby-doc.org/stdlib-2.6.1/libdoc/psych/rdoc/Psych.html#method-c-load.
If you're using pure Ruby (i.e. no Rails), you could intermediately change to JSON format. The JSON lib's parse method can symbolize keys.
http://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-parse
Here's what I mean:
JSON.parse(JSON.dump(YAML.load_file(File.expand_path('../app.yml', __FILE__))), symbolize_names: true)
Note: This adds overhead of conversion to and from json.
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__))) )
I usually don't use HashWithIndifferentAccess just to avoid confusion and prevent inconsistencies in the way that it is accessed, so what I would do instead is tack on a .deep_symbolize_keys to get the whole thing in symbol key form.
I'm trying to switch one of my websites into en-UK so that I get the correct date and currency formats etc...
I have found this yaml file:
http://github.com/mattetti/globalite/blob/master/lang/rails/en-UK.yml
Any ideas if there is a better one to use?
I also checked here but could not see it:
http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale
Thanks,
Nick
I have found a better solution than to keep a duplicate version of en.yml and simply change the $ to £.
There is a plugin that lets you only override the values you require:
http://github.com/javan/rails-i18n-translation-inheritance-helper
config/environment.rb
config.i18n.default_locale = 'en-UK'
and then create:
config/locales/en-UK.yml - for special cases
en-UK:
number:
currency:
format:
unit: '£'
format: '%u%n'
config/locales/en.yml - for all English translations
en:
btn_submit: Submit
This works a treat and will also mean that I don't need to maintain the file apart from any special cases like above.
View
=t 'btn_submit' #Submit
=h number_to_currency(#price, :precision => 0) #£1,000
Hope this helps others as it took a while to find a solution.
I think you're looking for en-GB :)
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en-GB.yml