9

我正在尝试编写一个将组件组合在一起的 Sinatra 应用程序(有点像控制器)。所以对于“博客”相关的东西,我想要一个名为Blogmount at的应用程序/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
4

2 回答 2

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 类的每个方面都将被其子类继承。这包括已定义的路由、所有错误处理程序、扩展、中间件等。

它有一些使用这种技术(和其他技术)的好例子。由于我处于无耻的插件模式,我推荐它,即使我与它无关!:)

于 2013-07-02T18:31:24.800 回答
0

我只是遇到同样的问题。

我发现任何inclued extend register或机架中间件样式use都有问题。

您可以使用 Ruby 来解决这样的问题:

require "sinatra"

class App < Sinatra::Base

  class << self
    def define_routes(&block)
      class_eval(&block)
    end
  end

end

App.define_routes do 

  get "/hello"
    "hello world"
  end
end
于 2022-02-13T04:53:53.983 回答