当您获得一个要从您那里继承的类时,Sinatra::Base
您就是在制作一个 Sinatra 应用程序。每个应用程序都有自己的 settings
对象。如果您想跨应用程序共享设置,您有一些选择:
- 合并应用程序。
- 使设置更易于全局访问。
- 继承(见下面的编辑)
合并它们很容易(除非有一些我们不知道的特殊原因),你基本上把它们放在同一个类中。
为了使设置更易于全局访问,我将执行以下操作:
a) 将整个应用程序包装在一个模块中以命名它。
b) 将您要使用的设置放入可通过“getter”方法访问的类实例变量中。
例如
module MyNamespace
def self.global_settings
@gs ||= # load your settings
end
class App < Sinatra::Base
configure do
set :something_from_the_global, MyNamespace.global_settings.something
end
end
class SecondaryApp < Sinatra::Base
helpers do
def another_method
MyNamespace.global_settings.something_else # available anywhere
end
end
configure do # they're also available here, since you set them up before the app
set :something_from_the_global, MyNamespace.global_settings.something
end
end
end
如果您有一些非常小的应用程序,那很好,但如果您使用多个应用程序,那么您需要将它们分开一点。我倾向于组织应用程序的方式是从 rackup 文件(通常是config.ru
)中删除除require
s 和run
. 我将中间件和应用程序设置放在另一个文件中,通常app/config.rb
这样我就知道它是来自config.ru
. 然后每个应用程序都有自己的文件(例如app/app.rb
, app/secondary.rb
)
# app/config.rb
require "app"
require "secondary"
module MyNamespace
# set up your getters… e.g.
def self.global_settings
@gs ||= # load your settings
end
def self.app
Rack::Builder.app do
# …and middleware here
use SecondaryApp
run App
end
end
end
# config.ru
require 'rubygems'
require 'bundler'
Bundler.require
root = File.expand_path File.dirname(__FILE__)
require File.join( root , "./app/config.rb" )
map "/" do
run MyNamespace.app
end
这种设置有很多好处——更容易测试;更容易组织;您可以更轻松地移动应用程序。但是YMMV一如既往。
我还应该补充一点,因为我很失职,所以也可以使用继承,例如:
require 'sinatra/base'
module MyNamespace
class Controller < Sinatra::Base
configure :development do
set :config, "some JSON"
set :mtime, Time.now.to_s
end
end
class App1 < Controller
get "/app1" do
"in App1 config: #{settings.config} mtime: #{settings.mtime}"
end
end
class App2 < Controller
get "/app2" do
"in App2 with config: #{settings. config} mtime: #{settings.mtime}"
end
end
end
设置、路由、助手、过滤器都是继承的,因此如果您在祖先应用程序中配置某些内容,它将在继承者中可用。有时这样做会更好,可能是当设置对 Sinatra 应用程序来说只是“全局”时,或者当您想要创建可重用的应用程序和控制器时。其他时候,您需要可在模型、库等中使用的设置,然后我首先给出的更具全局性的解决方案将是最好的。