Ruby on Rails: Can You Put Ruby Code in a Yaml Config File

Ruby on Rails: Can you put Ruby code in a YAML config file?

Not normally / directly. I say this because in order to use ruby results you need to use something like ERB first before loading the file. In terms of code, you need to go from something like:

loaded_data = YAML.load_file("my-file.yml")

Or even

loaded_data = YAML.load(File.read("my-file.yml"))

To:

loaded_data = YAML.load(ERB.new(File.read("my-file.yml")).result)

In this specific case, you would have to look at what is loading the file - in some cases,
it may already be designed to load it straight out of the environment or you may need to either:

  1. Monkey Patch the code
  2. Fork + Use your custom version.

Since there are a few plugins that use amazon_s3.yml, It might be worth posting which library you are using that uses it - alternatively, I believe from a quick google that the AWS library lets you define AMAZON_ACCESS_KEY_ID and AMAZON_SECRET_ACCESS_KEY as env vars and it will pick them up out of the box.

Ruby code in yaml file?

Rails' translation files don't permit Ruby, but they do have an interpolation mechanism. Try:

subject_reply: "You have got a new reply %{subject}"

See http://guides.rubyonrails.org/i18n.html#passing-variables-to-translations for more details.

Reading and updating YAML file by ruby code

Switch .load to .load_file and you should be good to go.

#!/usr/bin/env ruby
require 'yaml'
config = YAML.load_file('data.yml')
puts config['last_update']

After running this is what I get

orcus:~ user$ ruby test.rb
# ⇒ some_data

To write the file you will need to open the YAML file and write to the handle. Something like this should work.

require 'yaml'
config = YAML.load_file('data.yml')
puts config['last_update'] #in my file this is set to "some data"
config['last_update'] = "other data"
File.open('data.yml','w') do |h|
h.write config.to_yaml
end

Output was

orcus:~ user$ ruby test.rb
some data
orcus:~ user$ cat data.yml
---
last_update: other data

Rails use of yml file

Setting Rails environment variables. Using ENV variables in Rails, locally and with Heroku. Rails configuration and security with environment variables.

Environment Variables

Many applications require configuration of settings such as email account credentials or API keys for external services. You can pass local configuration settings to an application using environment variables.

Operating systems (Linux, Mac OS X, Windows) provide mechanisms to set local environment variables, as does Heroku and other deployment platforms. Here we show how to set local environment variables in the Unix shell. We also show two alternatives to set environment variables in your application without the Unix shell.

Gmail Example

config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: "example.com",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}

You could “hardcode” your Gmail username and password into the file but that would expose it to everyone who has access to your git repository. Instead use the Ruby variable ENV["GMAIL_USERNAME"] to obtain an environment variable. The variable can be used anywhere in a Rails application. Ruby will replace ENV["GMAIL_USERNAME"] with an environment variable.

Option One: Set Unix Environment Variables

export GMAIL_USERNAME="myname@gmail.com"

Option Two: Use the Figaro Gem

  • This gives you the convenience of using the same variables in code
    whether they are set by the Unix shell or the figaro gem’s
    config/application.yml. Variables in the config/application.yml file
    will override environment variables set in the Unix shell.
  • Use this syntax for setting different credentials in development,
    test, or production environments:

**

HELLO: world
development:
HELLO: developers
production:
HELLO: users

**

In this case, ENV["HELLO"] will produce “developers” in development, “users” in production and “world” otherwise.

Option Three: Use a local_env.yml File

Create a file config/local_env.yml:

Hope this help your answer!!!

Rails 4 - Yaml configuration file

If you are using Rails 4.2 or higher, you can use config_for for the config files. They need to be placed under /config folder. (haven't tried otherwise)

In your case it would be: config = Rails.application.config_for(:application)

This is more clear and Rails way to load configs into application.

Then you can use OpenStruct to have dot notation enabled for it.

APP_CONFIG = OpenStruct.new(config)

What's a good approach for loading a YAML config in Ruby but setting default values?

You should prepare a default hash, and then overwrite the values from the configure by merging the hash.

default_app_config = {
"app_name" => "Default name",
"app_path" => "default/path",
...,
}

app_config = default_app_config.merge(YAML.load_config("config.yml"))

Sharing Yaml config files between Sinatra and Rails

If you’re including your Sinatra app by mounting it with an entry in your config/routes.rb, you can configure it by calling methods on it before the mount call.

Any methods you call here will run after any configure blocks in your app, so if you want to do anything more complex than setting a single variable (with the Sinatra set command) you will need to add a class method that you can call from routes.rb.

For example, if you want to have a Yaml config file that contains an entry foo, then in your Sinatra app add something like:

def self.config_from_file(filename)
data = YAML.load_file(filename)
set :foo, data['foo']
# set other vars from Yaml as appropriate
end

Now settings.foo will be available in your routes.

In your Rails config/routes.rb you will need to add something like:

# first configure your app
MyApp.config_from_file(File.join("#{Rails.root}/config", "foo_config.yaml"))
# now mount it at the appropriate url
mount MyApp.new => '/foo'

Ruby On Rails: How to write yml configurations in a file when deploying with Capistrano 3?

I had trouble with this solution, because capistrano 3 replaces newlines with semicolons. So here is my code:

namespace :setup do
task :setup_database do
ask(:db_user, 'db_user')
ask(:db_pass, 'db_pass')
ask(:db_name, 'db_name')
db_config = <<-EOF
production:
adapter: mysql2
database: #{fetch(:db_name)}
username: #{fetch(:db_user)}
password: #{fetch(:db_pass)}
EOF

on roles(:app) do
execute "mkdir -p #{shared_path}/config"
upload! StringIO.new(db_config), "#{shared_path}/config/database.yml"
end
end
end

Rails Yaml Config (Best Practice)

I've been using this gem for that purpose recently:

  • SettingsLogic: https://github.com/binarylogic/settingslogic

Basically, you create a /config/application.yml file that looks something like this:

defaults: &defaults
api:
johns_api_co:
api_key: my_key
secret: shh!!!

other_setting:
this: "is a config setting"
that: "and another thing"

development:
<<: *defaults

test:
<<: *defaults

production:
<<: *defaults

There are so many ways to do this, but this works well and is pretty straightforward.



Related Topics



Leave a reply



Submit