【问题标题】:How to mount a Sinatra application inside another Sinatra app?如何在另一个 Sinatra 应用程序中安装 Sinatra 应用程序?
【发布时间】:2012-07-16 00:19:28
【问题描述】:

我正在尝试编写一个将组件组合在一起的 Sinatra 应用程序(有点像控制器)。所以对于“博客”相关的事情,我想要一个名为Blog 的应用程序安装在/blogBlog 应用程序中包含的所有路由都与其挂载路径相关,因此我可以简单地定义一个index 路由,而无需在路由中指定挂载路径。

我最初通过使用 config.ru 文件和maping 到不同应用程序的路由来处理这个问题。我遇到的问题是我使用了各种需要包含在所有应用程序中的 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

【问题讨论】:

  • 我一直在寻找相同的方法,但似乎我们无法在 Sinatra 上做到这一点。但我找到了一个可以做到这一点的微框架,它真的很棒。看看into cuba。这不是一个完美的解决方案,但您可以在古巴进行下一个项目。
  • 你能提供一个你想要的例子吗(在代码中)?
  • @Jeffrey 我添加了一个伪代码示例
  • 据我所知,每个 sinatra 应用程序都有一个路由哈希。当您实现 mount 方法时,使其遍历应用程序的路由并将前缀添加到路径中。你明白我的意思吗?
  • 这是一个使用 Rack::URLMap 的示例,以防我将来决定使用它:stackoverflow.com/questions/6496433/…

标签: ruby sinatra


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我也遇到了同样的问题。

    我发现无论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
    

    【讨论】:

      猜你喜欢
      • 2013-01-03
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 2015-07-30
      • 1970-01-01
      • 2018-02-28
      相关资源
      最近更新 更多