Reputation: 33
I'm trying to write a config.ru file for Sinatra where I have one set of database credentials for each environment: development and production. I'm doing the following:
app.rb:
require 'sinatra'
require 'data_mapper'
require 'dm-mysql-adapter'
DataMapper.setup(:default, "mysql://#{settings.db_user}:#{settings.db_password}@#{settings.db_host}/#{settings.db_name}")
# ... the rest of the app
config.ru:
require 'sinatra'
require './app.rb' # the app itself
configure :development do
set :db_name, 'thedatabase'
set :db_user, 'root'
set :db_password, ''
set :db_server, 'localhost'
end
run Sinatra::Application
But when I attempt to start the app using ruby app.rb
, I get "undefined method 'db_user' for Sinatra::Application:Class (NoMethodError)".
Generally, I'm just trying to offload all these settings into their own file. If config.ru isn't the place for them, what would be an appropriate way to do this?
Upvotes: 2
Views: 2793
Reputation: 11
config.ru is only going to be used if you start your app with rakeup. If you start your app with 'ruby app.rb', config.ru is not going to come into play.
Upvotes: 0
Reputation: 10378
I agree with Thomas. This has been confusing for me at times too, thus I want to show you why this works like this. Here is how Ruby interprets requires and class openings.
#user.rb
class User
def hello
puts "hello"
end
end
#config.ru
require 'user' # Here we include the original User class
class User # on this line we reopen the user class
def goodbye # We add a new method to the user class
puts "goodbye"
end
end
If we call user somewhere after the user require
in config.ru, but before reopening the class, we can not access the goodbye
method. However, after reopening the class definition and adding it we can. This is also the function of the Sinatra set
method and is why it can only be called inside an open Sinatra class. That is why you sometimes also see alternative ways not using the set
method. requiring or including things in the Sinatra class in your config.ru will make the widely available in your Sinatra applications.
Another common thing that causes problems is that Sinatra is built upon Rack thus opening Rack class and configuring stuff there can also make these changes available in Sinatra.
Upvotes: 0
Reputation: 181745
Looks like it might be an ordering problem. If that DataMapper.setup(...)
line is really at the top level of app.rb
, it will be called as soon as you require './app.rb'
, before configure
has run.
It's best not to do any work upon loading a file. Use some form of explicit or lazy initialization instead.
Upvotes: 3