Can a YML file access another YML file? - ruby-on-rails

We have a site wide config.yml file which contacts api keys etc...
Can another one of my YML files access a value in the config.yml?
config.yml:
development:
thing: 123123123123
plugin_config.yml:
development:
thing: config.yml.development.thing
is this possible?

You can always parse it with ERB:
development:
thing: 123123123123
development:
thing: <%= YAML.load(ERB.new(File.read(Rails.root.join('config','config.yml'))).result)['development'] %>
Then load the first one and also parse it with ERB (in an initializer or something):
CONFIG = YAML.load(ERB.new(File.read(Rails.root.join('config','plugin_config.yml'))).result)

Related

Rails: configuring applications

I am reading and coding along with a tutorial.
I have an application.yml file with some constants created to hold data. To include those constants in ENV and initialize them at start, this code was given :
config_file = Rails.application.config_for(:application) #this is the bothersome part
config_file.each do |key,value|
ENV[key] = value
end unless config_file.nil?
I fail to fully understand this code. In particular, on the first line, where do the chained objects come from what do they mean and how do I create such on my own ?
It loads data from a config file into the app. The example from the docs about #config_for:
#config/app.yml:
production:
url: http://127.0.0.1:8080
namespace: my_app_production
development:
url: http://localhost:3001
namespace: my_app_development
If you do rails c and type Rails.application.config_for(:app) into the console, you'll get:
{"url"=>"http://localhost:3001", "namespace"=>"my_app_development"}
which is just a regular hash you can loop through using #each or access it's values through keys.

Which Rails files are parsed through ERB first?

I was looking through a new default Rails application, and in config/database.yml I noticed a snippet of ERB:
...
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> # <-- ERB
timeout: 5000
...
Now, I know what ERB is and how it works. What I'm confused by is the fact that the fact a file contains ERB is usually indicated in the file name. For example, a view file might be called index.html.erb.
It's a sort of trivial point, and it might be that the answer is "they just didn't feel like it, it's their package", but why isn't this file called (say) database.yml.erb? The name as it stands suggests it should just contain plain YAML, and it doesn't.
This is indeed a special case. At some point the strategy outlined http://urgetopunt.com/2009/09/12/yaml-config-with-erb.html became the default. I tried to find where in GitHub, but didn't find the exact date of when this happened.

mongoid yaml combines environment variables for hosts

I am new to rails and mongoid, I have mongoid.yml file that contains the entries as follows:
development:
# Configure available database clients. (required)
clients:
# Defines the default client. (required)
default:
# Defines the name of the default database that Mongoid can connect to.
# (required).
database: mycollectionname
# Provides the hosts the default client can connect to. Must be an array
# of host:port pairs. (required)
hosts:
- localhost:27017
this works properly for development, however, in production, I'd like to specify the host from environment variables like ENV['OPENSHIFT_MONGODB_DB_HOST'] + ":" + ENV['OPENSHIFT_MONGODB_DB_PORT']
I've tried various ways such as this
hosts:
- <%= \"#{ENV['OPENSHIFT_MONGODB_HOST']}:#{ENV['OPENSHIFT_MONGODB_PORT']}\" %>
or
hosts:
- #{ENV['OPENSHIFT_MONGODB_HOST']:ENV['OPENSHIFT_MONGODB_PORT']}
etc, but none works
In yaml code, <%= %> is meant for you to insert ruby code, you can use Expression Substitution inside it to format your url
Expression substitution is a means of embedding the value of any Ruby expression into a string using #{ and }
Something like this will do:
<%= "#{ENV['OPENSHIFT_MONGODB_HOST']}:#{ENV['OPENSHIFT_MONGODB_PORT']}" %>
In my mongoid project with openshift, I am using its uri: field like this:
uri: <%= "#{ENV['OPENSHIFT_MONGODB_DB_URL']}#{ENV['OPENSHIFT_APP_NAME']}" %>
Please also pay attention to the indentation, it has to be accurate and it has to be space! Tab will cause problems too!

Issues using config/secrets.yml variable set from ENV variable on Rails 4.1.0

Have not played with Rails in ages so walking through the Learn Ruby on Rails tutorial which is excellent.
I'm having issues with google authentication, the example code calls the config/secrets.yml variables (which are read from ENV in the shell) from the app/models/contact.rb model update_spreadsheet method below
def update_spreadsheet
connection = GoogleDrive.login(Rails.application.secrets.gmail_username, Rails.application.secrets.gmail_password)
I have the ENV variable set via my ~/.bash_profile and have confirmed using the following code I can make things work, but it's not the example code so I'm just hacking.
def update_spreadsheet
connection = GoogleDrive.login(ENV["GMAIL_USERNAME"], ENV["GMAIL_PASSWORD"])
I can make it work but, I wanted to follow the tutorial and know how to troubleshoot better. if anyone has a pointer it would be appreciated.
Inside my config/secrets.yml file looks like:
development:
gmail_username: <%= ENV["GMAIL_USERNAME"] %>
gmail_password: <%= ENV["GMAIL_PASSWORD"] %>
Thank you
Rails reads secrets.yml but getting the value from secrets.yml is little different then how you had used it, check the code below:
secrets.yml:
development:
secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
some_api_key: SOMEKEY
This is how you can access the value:
Rails.application.secrets.some_api_key returns SOMEKEY
I was having the same issue here and followed all the instructions here and was still experiencing difficulties. My gmail password does not have any special characters, but in my .bash profile I just tried putting single quotes around the contents of the double quotes for both GMAIL_USERNAME and GMAIL_PASSWORD, and it finally worked!
The above solution did not work for me. However, I found the solution on How do I use variables in a YAML file?
My .yml file contained something like:
development:
gmail_username: <%= ENV["GMAIL_USERNAME"] %>
gmail_password: <%= ENV["GMAIL_PASSWORD"] %>
In your .rb file,access the yml file as:
template = ERB.new File.new("path/to/config.yml.erb").read
processed = YAML.load template.result(binding)
So when you introduce a scriptlet tag in .yml file, it is more of erb template. So read it as a erb template first and then load the yml as shown above.

Rails - Global Variables to be used anywhere, including controller, views, and models

My question is seemingly simple but has been pretty elusive. I want one value that can be called anywhere in the application - it's a minimum value we are using for validations in the model, we want to inform the user of that value, etc.
So far, I have done the following:
In config/initializers, I created a new .rb file (under suggestion I found on another thread):
minimum = 15
and only got that it couldn't be found after starting rails server.
I found a strange suggestion to put the value in en.yml as minimum: 15, same issue as above.
Obviously, application helper and controller won't help as I need the value in my models. I did however find one solution, which was to put it in the class Application in config/application.rb:
config.after_initialize do
::Minimum = 15
end
and afterwards call it like this:
MyApp::Application::Minimum
Obviously, this solution, while it does work, isn't ideal. If I could find a way to alias MyApp::Application::Minimum as just "minimum", I'll be completely satisfied, but getting it done in the initializers is, from what I've heard, a better solution.
You can stick something in a model if you want and call it from anywhere:
Couriers = %w[TNT UPS RoyalMail Bike Hand Pigeon Other]
But I prefer putting them in a yaml file.
Create a config.yml file in your configs directory and put your vars in there:
defaults: &defaults
node_1: '10.8'
node_2: '10.9'
node_3: '10.0'
whatever: 1
thereis: 2
development:
<<: *defaults
playground:
<<: *defaults
production:
<<: *defaults
poststaging:
<<: *defaults
test:
<<: *defaults
Load the config file using something like this in your initializers directory. Create a file in /config/initializers called 'load_vars.rb' and put the following in there:
SETTINGS = YAML.load_file("#{Rails.root}/config/config.yml")[Rails.env]
You'll have to restart your server after changing these though.
-- EDIT --
To use these variables, you can load with something like this from your model, controller, views:
SETTINGS['var_1']

Resources