Архитектура для модульного, компонентного приложения Sinatra

Я работаю над приложением Sinatra, которое содержит около 10 различных компонентов функциональности. Мы хотели бы иметь возможность смешивать и сопоставлять эти компоненты с отдельными экземплярами приложения, полностью настраиваемыми из файла 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" из файла конфигурации, используемого для базы.

Каков наилучший способ организовать и создать экземпляр кода модуля?

Ответ 1

Это похоже на предложение, но оно не требует доступа к файлу в стойке.

Напишите ваши различные обработчики, например:

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

Ответ 2

TIMTOWTDI - There_s_more_than_one_way_to_do_it:), и это одно. Но на самом деле я использую другой путь. Я использую Sinatra/Base для создания модульных приложений.

У меня есть маршруты для каждого приложения.

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

получайте удовольствие:)