2

我正在尝试为 Sinatra 编写一个 config.ru 文件,其中每个环境都有一组数据库凭据:开发和生产。我正在执行以下操作:

应用程序.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

配置.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

但是当我尝试使用 启动应用程序时ruby app.rb,我得到“Sinatra::Application:Class (NoMethodError) 的未定义方法 'db_user'”。

一般来说,我只是想将所有这些设置卸载到他们自己的文件中。如果 config.ru 不适合他们,那么合适的方法是什么?

4

3 回答 3

3

看起来这可能是一个订购问题。如果那条DataMapper.setup(...)线真的在 的顶层app.rb,它会在你require './app.rb', beforeconfigure运行后立即调用。

加载文件时最好不要做任何工作。改用某种形式的显式或延迟初始化。

于 2013-01-20T22:27:52.673 回答
0

我同意托马斯的观点。这有时也让我感到困惑,因此我想向您展示为什么会这样。以下是 Ruby 解释需求和类开放的方式。

#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

如果我们在 config.ru 中的用户之后的某个地方调用 user require,但在重新打开类之前,我们无法访问该goodbye方法。但是,在重新打开类定义并添加它之后,我们可以。这也是 Sinatraset方法的功能,也是为什么它只能在开放的 Sinatra 类中调用的原因。这就是为什么您有时还会看到不使用该方法的替代set方法。在您的 config.ru 中要求或包含 Sinatra 类中的内容将在您的 Sinatra 应用程序中广泛使用。

另一个导致问题的常见事情是 Sinatra 是基于 Rack 构建的,因此打开 Rack 类并在那里配置东西也可以使这些更改在 Sinatra 中可用。

于 2013-01-21T08:27:05.223 回答
0

config.ru 只有在你使用 rakeup 启动你的应用程序时才会被使用。如果您使用 'ruby app.rb' 启动您的应用程序,则 config.ru 不会发挥作用。

于 2016-11-05T05:25:23.997 回答