2011-09-01 33 views
10

Tôi đang làm việc trên ứng dụng Sinatra chứa khoảng 10 thành phần chức năng khác nhau. Chúng tôi muốn để có thể trộn và kết hợp các thành phần này vào trường hợp riêng biệt của ứng dụng, cấu hình hoàn toàn từ một tập tin config.yaml trông giống như sau:Kiến trúc cho một ứng dụng Sinatra dựa trên thành phần mô-đun,

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 

Như bạn có thể thấy, các thành phần có thể được khởi tạo hơn hơn một lần, mỗi cài đặt theo ngữ cảnh của riêng họ.

Mỗi thành phần bao gồm ít nhất một tuyến đường, với thuộc tính "tuyến đường" từ tệp cấu hình được sử dụng cho cơ sở.

Cách tốt nhất để sắp xếp và khởi tạo mã mô-đun là gì?

Trả lời

10

Điều này tương tự bao gồm của đề xuất, nhưng nó không đòi hỏi quyền truy cập vào các tập tin rackup.

Viết Handlers khác nhau của bạn như:

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

Sau đó, trong tập tin ứng dụng chính của bạn:

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

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

Tôi đã sử dụng loại cấu trúc để xây dựng một số ứng dụng Sinatra khá phức tạp. Nó quy mô cũng như Rails.

EDIT

Để có tập tin cấu hình của bạn xác định các tuyến đường, bạn có thể làm một cái gì đó như thế này:

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

Vị trí này gần nhưng không tính đến định tuyến động được đề cập trong câu hỏi. tức là '/ chunky' không thể được mã hóa cứng. –

+0

Điểm tốt. Xem phần chỉnh sửa. – bioneuralnet

+0

Đẹp! Đã không nghĩ đến việc lặp lại bên trong mã mở rộng. Lưu ý cuối cùng: Ý của bạn là 'mở rộng' thay vì' sử dụng'? Tôi không thể tìm thấy tài liệu về 'use'. –

2

TIMTOWTDI - There_more_than_one_way_to_do_it :) và đó là một. Nhưng trên thực tế tôi sử dụng một cách khác. Tôi sử dụng Sinatra/Base cho các ứng dụng mô-đun dev.

Tôi có các tuyến đường mô phỏng cho từng ứng dụng.

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

Bạn có thể có bộ biến cho từng trường hợp. Bạn có thể phát triển mỗi 'thành phần' trên Mô-đun của nó.

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 } 

    #... 

Đó là giao diện tại đây. http://codex.heroku.com/

vui chơi :)

+0

Drats! Tôi figured giải pháp này sẽ đi lên, và gần như xem xét thêm nó vào câu hỏi vì nó chỉ là không thể trong trường hợp của chúng tôi (các tập tin rackup là ngoài tầm với). Nếu không có giải pháp nào khác xuất hiện, tôi sẽ chọn giải pháp này! –

Các vấn đề liên quan