helper function in database.yml not working from rake

hello group,

in
order not to have passwords stored in my database.yml, I had inserted a
function that read the password from a file that is not under version control.

The entry in database.yml looks like this:

e:
adapter: postgresql
host: localhost
template: template0
database: archive_e
encoding: utf8
username: archive_e
password: <%= read_pwd() %>
pool: 5 # not mandatory
timeout: 500

In config/environment.rb the function was defined:

Load the rails application

require File.expand_path(’…/application’, FILE)

def read_pwd ()
File.open( File.join( File.dirname( FILE), ‘.pwd’), ‘r’) do |fh|
fh.read
end
end

Initialize the rails application

Varch::Application.initialize!

This
seemed to be a nice solution for quite some time, until I today had to rebuild my database. When I now try a db:setup or db:migrate, I get this
error:

$ rake db:setup RAILS_ENV=e
/home/ruud/.rvm/gems/ruby-1.9.3-p551@rails32/gems/rspec-core-3.3.2/lib/rspec/core/shell_escape.rb:30:
warning: already initialized constant SHELLS_ALLOWING_UNQUOTED_IDS
rake aborted!
NoMethodError: undefined method read_pwd' for main:Object (erb):8:in
/home/ruud/.rvm/gems/ruby-1.9.3-p551@rails32/gems/railties-3.2.17/lib/rails/application/configuration.rb:115:in
database_configuration' /home/ruud/.rvm/gems/ruby-1.9.3-p551@rails32/gems/activerecord-3.2.17/lib/active_record/railties/databases.rake:25:in block (2 levels) in <top (required)>’
/home/ruud/.rvm/gems/ruby-1.9.3-p551@rails32/bin/ruby_executable_hooks:15:in eval' /home/ruud/.rvm/gems/ruby-1.9.3-p551@rails32/bin/ruby_executable_hooks:15:in
Tasks: TOP => db:setup => db:schema:load_if_ruby => db:create => db:load_config
(See full trace by running task with --trace)
[1] 19621 exit 1 rake db:setup RAILS_ENV=e

It must be very simple to solve this, but I would greatfully accept any help; I am out of ideas at the moment. I don’t know how to instruct rake to include the file in which read_pwd is defined.

thanks in advance, Ruud

Why not just use an environment variable. For example, <%= ENV[‘MY_DB_PASSWORD’] %>. Then you can export that from your specific environment or fire up your task with the environment var set, ex: MY_DB_PASSWORD=letsparty rails s

I second that - support for environment variables is already built into the loader of database.yml

Hi Matt,
thanks for your advice. Maybe this is an alternative in this case, but I would like to know how to tackle this for custom functions in general.
I found out that if I copy the function to config/application, rake finds it. If it is the proper solution for yml-helper functions I don’t know. Maybe someone has advice on this.

Ruud

Not exactly the same thing but I have a config/storage.yml file for holding my S3 configuration - and I load it in config/initializers/storage.rb - load the YAML as a text file, use ERB to parse it and then apply the file. So any functions I had defined within config/initializers/storage.rb should be available to the ERB parser.

contents = File.open(File.join(Rails.root, ‘config’, ‘storage.yml’)) { | f | f.read }

contents = ERB.new(contents).result

yaml = YAML.load(contents)

AqrReports::Application.config.image_options = yaml[‘images’][Rails.env]

AqrReports::Application.config.file_options = yaml[‘files’][Rails.env]

Hi Rahoul,
I am going to try that. Thanks for your help.

regards, Ruud

Rahoul Baruah <lists@madeofstone.net> writes:

Hi Matt,
thanks for your advice. Maybe this is an alternative in this case, but I
would like to know how to tackle this for custom functions in general.
I found out that if I copy the function to config/application, rake finds
it. If it is the proper solution for yml-helper functions I don't know.
Maybe someone has advice on this.

Not exactly the same thing but I have a config/storage.yml file for holding
my S3 configuration - and I load it in config/initializers/storage.rb -
load the YAML as a text file, use ERB to parse it and then apply the file.
So any functions I had defined within config/initializers/storage.rb
should be available to the ERB parser.

contents = File.open(File.join(Rails.root, 'config', 'storage.yml')) { | f
> f.read }
contents = ERB.new(contents).result
yaml = YAML.load(contents)

AqrReports::Application.config.image_options = yaml['images'][Rails.env]
AqrReports::Application.config.file_options = yaml['files'][Rails.env]

This is for Rahoul, not the OP:

Rails 4.1 introduced the #config_for method on the Rails application,
which makes all the reading, erbing, and yamling of config files really
super simple. You can change your above initializer to:

    STORAGE_CONFIG = Rails.application.config_for(:storage)
    AqrReports::Application.config.image_options = STORAGE_CONFIG['images']
    AqrReports::Application.config.file_options = STORAGE_CONFIG['files']

From the looks of things, you may need to rearrange your storage.yml to
be in the same structure as database.yml.

This is for Rahoul, not the OP:

Rails 4.1 introduced the #config_for method on the Rails application,

which makes all the reading, erbing, and yamling of config files really

super simple. You can change your above initializer to:

Thanks Tamara - I must have completely missed that. It looks awesome.

I guess the OP would still need to do the ERB stuff by hand to get custom functions in there though.

Cheers

Rahoul

http://theartandscienceofruby.com/