Search code examples
ruby-on-railsrubyrabbitmqyamlbunny

How to pass parameters from a yaml file to a constructor, without expicitly mentioning each one?


I have this initialiser script for setting my RabbitMq connection using Bunny:

require 'yaml'
config = YAML.load_file('config/rabbitmq.yml')

puts config[Rails.env]
# $bunny = Bunny.new(config[Rails.env])

$bunny = Bunny.new(:host => config[Rails.env]["host"],
         :vhost => config[Rails.env]["vhost"],
         :user => config[Rails.env]["user"],
         :password => config[Rails.env]["password"],
)

$bunny.start
$bunny_channel = $bunny.create_channel

The contents of config[Rails.env] are:

{"<<"=>nil, "host"=>"spotted-monkey.rmq.cloudamqp.com", "user"=>"myuser", "password"=>"mypassord", "vhost"=>"myvhost"}

The verbose syntax of the Bunny.new command works correctly. However, when I comment out the verbose block, and leave this syntax:

$bunny = Bunny.new(config[Rails.env])

I get the following error message:

session.rb:296:in `rescue in start': Could not establish TCP connection to any of the configured hosts (Bunny::TCPConnectionFailedForAllHosts)

I was expecting it to work, since the keys are the same in both cases. Is there any way to call the constructor without specifying each parameter explicitly?

I tried to remove the "<<"=>nil line from the yaml file, with no change in behaviour.


Solution

  • Having look into source code I found this:

    def hostnames_from(options)
      options.fetch(:hosts_shuffle_strategy, @default_hosts_shuffle_strategy).call(
        [ options[:hosts] || options[:host] || options[:hostname] || DEFAULT_HOST ].flatten
      )
    end
    

    It seems it is expecting a symbol :host not, string 'host' which is practicaly the only difference between two ways you're calling initializer. Try:

    config = HashWithIndifferentAccess.new YAML.load_file('config/rabbitmq.yml')