基于组件的模块化Sinatra应用程序的体系结构

我正在研究一个包含大约10个不同function组件的Sinatra应用程序。 我们希望能够将这些组件混合并匹配到应用程序的单独实例中,完全由config.yaml文件配置,类似于:

components: - route: '/chunky' component_type: FoodLister component_settings: food_type: bacon max_items: 400 - route: 'places/paris' component_type: Mapper component_settings: latitude: 48.85387273165654 longitude: 2.340087890625 - route: 'places/losangeles' component_type: Mapper component_settings: latitude: 34.043556504127466 longitude: -118.23486328125 

如您所见,组件可以多次实例化,每个组件都有自己的上下文设置。

每个组件至少包含一个路由,其中​​“route”属性来自用于基础的配置文件。

组织和实例化模块代码的最佳方法是什么?

这类似于include的提议,但它不需要访问rackup文件。

写你的各种处理程序,如:

 class FoodHandler < Sinatra::Base get '/chunky/:food' do "Chunky #{params[:food]}!" end end 

然后在您的主应用程序文件中:

 require './lib/handlers/food_handler.rb' class Main < Sinatra::Base enable :sessions ... bla bla bla use FoodHandler end 

我已经使用这种结构来构建一些相当复杂的Sinatra应用程序。 它的扩展与Rails一样。

编辑

要让您的配置文件定义路由,您可以执行以下操作:

 class PlacesHandler < Sinatra::Base # Given your example, this would define 'places/paris' and 'places/losangeles' CONFIG['components'].select { |c| c['compontent_type'] == 'Mapper' }.each do |c| get c['route'] do @latitude = c['component_settings']['latitude'] @longitude = c['component_settings']['longitude'] end end end 

TIMTOWTDI – there_more_than_one_way_to_do_it :)这是一个。 但实际上我用另一种方式。 我使用Sinatra / Base开发模块化应用程序。

我有每个应用程序的simgle路线。

 # config.ru file require 'bundler/setup' Bundler.require(:default) require File.dirname(__FILE__) + "/main.rb" map "/" { run BONES::Main } map "/dashboard" { run BONES::Dashboard } map "/app1" { run BONES::App1 } 

您可以为每个实例设置变量集。 您可以在其模块上开发每个“组件”。

 require File.dirname(__FILE__) + "/lib/helpers.rb" module BONES class Main < Sinatra::Base helpers XIXA::Helpers configure :development do enable :sessions, :clean_trace, :inline_templates disable :logging, :dump_errors set :static, true set :public, 'public' end enable :static, :session set :root, File.dirname(__FILE__) set :custom_option, 'hello' set :haml, { :format => :html5 } #... 

那看一看。 http://codex.heroku.com/

玩得开心 :)