Sinatra的通用设置

时间:2013-02-13 03:41:57

标签: ruby sinatra

我在Sinatra有一个班级,我设置了一些设置(来自JSON,因为它发生了):

class Pavo < Sinatra::Base
  configure :development do
    set :config, JSON.parse(File.open(File.dirname(__FILE__) + "/pavo.configuration.development.json", "rb").read)
    set :config_mtime, File.mtime(File.dirname(__FILE__) + "/pavo.configuration.development.json")
  end

  [...]

  get '/' do
    puts "whatever"
  end
end

该类有一个模型,需要读取这些设置。

class Resolver < Sinatra::Base
  def get_data(workpid)
    url_str = settings.config['public']['BOOKS_DATA_SERVICE_URL'].gsub('${WORKPID}', workpid)
    return Resolver.get_json(url_str)
  end
  [...]
end

然而,解析器类不能这样做:未定义的方法`config&#39;解析器:Class。

也许我的范围有误,或者我应该使用Sinatra :: Application?

1 个答案:

答案 0 :(得分:3)

当你从Sinatra::Base继承一个类时,你正在制作一个Sinatra应用程序。每个应用程序都获得自己的 settings对象。如果您想跨应用程序共享设置,您有一些选择:

  1. 合并应用程序。
  2. 使设置更易于全局访问。
  3. 继承(参见下面的编辑)
  4. 合并它们很容易(除非有一些我们不知道的特殊原因),你基本上把它们放在同一个类中。

    为了使设置更易于全局访问,我将执行以下操作:

    a)将整个应用程序包装在一个模块中以命名它 b)将要使用的设置放在可通过“getter”方法访问的类实例变量中。

    e.g。

    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
    

    如果您有一些非常小的应用程序,这很好,但如果您使用多个应用程序,那么您将需要稍微分开一些。除了config.rurequire之外,我倾向于组织应用的方式是从除了runapp/config.rb之外的任何内容的rackup文件(通常是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 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

    {{1}}

    这种设置有很多好处 - 它更容易测试;它更容易组织;你可以更容易地移动应用程序。但YMMV一如既往。


    我还应该补充一点,因为我不能理解,也可以使用继承,例如:

    {{1}}

    设置,路由,帮助程序,过滤器都是继承的,因此如果您在祖先应用程序中配置某些内容,它将在继承者中可用。有时这样做会更好,可能是当设置只是Sinatra应用程序的“全局”或者你想创建可重用的应用程序和控制器时。其他时候,你需要可以在模型,库等中使用的设置,然后我首先给出的更全局的解决方案是最好的。