我正在尝试编写一个将组件组合在一起的Sinatra应用程序(有点像控制器)。因此,对于与“博客”相关的内容,我希望在Blog
处安装一个名为/blog
的应用。 Blog
应用程序中包含的所有路由都与其安装路径相关,因此我可以简单地定义index
路由,而无需在路由中指定安装路径。
我最初使用config.ru文件和map
路由到不同的应用程序来处理这个问题。我遇到的问题是,我使用的是所有应用程序中需要包含的各种sinatra gems / extensions / helper,因此有很多重复的代码。
如何在另一个应用程序中安装一个sinatra应用程序,以便应用程序中定义的路径相对于应用程序的安装位置?如果这不可能是开箱即用的,你能否展示如何做到这一点的代码示例?
以下是一个简单的示例:
class App
mount Blog, at: '/blog'
mount Foo, at: '/bar'
end
class Blog
get '/' do
# index action
end
end
class Foo
get '/' do
# index action
end
end
答案 0 :(得分:3)
请查看https://stackoverflow.com/a/15699791/335847,其中包含有关命名空间的一些想法。
就个人而言,我会将config.ru用于映射路由。如果你真的在这个空间“应该是一个单独的应用程序还是仅仅像这样组织它有用”它允许这样,然后你仍然可以自己移除其中一个应用程序,而无需更改代码(或只是一点点)。如果你发现有很多重复的设置代码,我会做这样的事情:
# base_controller.rb
require 'sinatra/base'
require "haml"
# now come some shameless plugs for extensions I maintain :)
require "sinatra/partial"
require "sinatra/exstatic_assets"
module MyAmazingApp
class BaseController < Sinatra::Base
register Sinatra::Partial
register Sinatra::Exstatic
end
class Blog < BaseController
# this gets all the stuff already registered.
end
class Foo < BaseController
# this does too!
end
end
# config.ru
# this is just me being lazy
# it'd add in the /base_controller route too, so you
# may want to change it slightly :)
MyAmazingApp.constants.each do |const|
map "/#{const.name.downcase}" do
run const
end
end
以下是Sinatra Up and Running的引用:
不仅设置,而且Sinatra类的每个方面都将由其子类继承。这包括已定义的路由,所有错误处理程序,扩展,中间件等。
它有一些使用这种技术(和其他)的好例子。由于我处于无耻的插件模式,我推荐它,即使我与它无关! :)