2011-09-01 23 views
10

Estoy trabajando en una aplicación Sinatra que contiene aproximadamente 10 componentes diferentes de funcionalidad. Nos gustaría ser capaz de mezclar y combinar estos componentes en instancias independientes de la aplicación, configurados por completo de un archivo config.yaml que se ve algo como:Arquitectura para una aplicación Sinatra modular basada en componentes

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 

Como se puede ver, los componentes se pueden crear instancias más más de una vez, cada uno con su propia configuración contextual.

Cada componente consta de al menos una ruta, con la propiedad "ruta" del archivo de configuración utilizado para la base.

¿Cuál es la mejor manera de organizar y crear instancias del código del módulo?

Respuesta

10

Esto es similar a incluir de propuesta, pero no requiere el acceso al archivo rackup.

ESCRIBE diversos Manipuladores como:

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

A continuación, en el archivo principal de la aplicación:

require './lib/handlers/food_handler.rb' 

class Main < Sinatra::Base 
    enable :sessions 
    ... bla bla bla 
    use FoodHandler 
end 

He utilizado este tipo de estructura para construir algunas aplicaciones Sinatra bastante complejas. Se escala tan bien como Rails.

EDITAR

Para que el archivo de configuración a definir las rutas, se podría hacer algo como esto:

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 
+0

Esto está cerca, pero no tiene en cuenta el enrutamiento dinámico mencionado en la pregunta. es decir, '/ grueso' no puede ser codificado. –

+0

Buen punto. Vea la edición sobre. – bioneuralnet

+0

¡Agradable! No había pensado en iterar dentro del código de extensión. Última nota: ¿Quiso decir 'extender' en lugar de' usar'? Parece que no puedo encontrar la documentación del 'uso'. –

2

TIMTOWTDI - Hay_más_de_una_máquina_para_hacia_ :) y esa es una. Pero, de hecho, uso otra forma. Yo uso Sinatra/Base para aplicaciones mod dev.

Tengo rutas de simulación para cada aplicación.

# 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 } 

Puede tener conjuntos de variables para cada instancia. Puede desarrollar cada 'componente' en su Módulo.

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 } 

    #... 

Que un vistazo aquí. http://codex.heroku.com/

divertirse :)

+0

drats! Pensé que esta solución surgiría, y casi consideré agregarla a la pregunta, ya que simplemente no es posible en nuestro caso (el archivo de rackup está fuera de nuestro alcance). Si no aparece otra solución, ¡seleccionaré esta! –

Cuestiones relacionadas