如何将路由映射到 Sinatra 中的控制器?

How to map routes to controllers in Sinatra?

我想使用 Sinatra 创建一个简单的实验性 MVC 框架。

我想按名称定义资源 "pages" 例如应该解析为:

/pages (index)
/pages/new
/pages/:id/show (show)

以及map到app/controllers/PagesController.rb对应get('/')负责索引,post('/pages/create')负责创建等

麻烦的是,即使在阅读了官方文档之后我也感到非常困惑。我想我需要为此使用非经典 Sinatra 模型,但有人能指出正确的方向吗?

谢谢

我在这里给你一个非常简单的例子:

创建文件controller.rb

get '/pages' do
  @pages = Pages.all
  erb :pages
end

接下来在与控制器相同的文件夹中创建一个 views 目录,并创建一个名为 pages.html.erb

的文件

这是您之前创建的控制器操作的对应视图。

在这里,您可以输入如下内容:

<% @pages.each do |p| %>
<%= p.title %>
<% end %>

重新启动您的服务器,访问 localhost:PORT/pages,您将看到所有页面标题的列表。

您可以查看此 link 以获得简单的 sinatra 教程 - http://code.tutsplus.com/tutorials/singing-with-sinatra--net-18965

您可以根据需要使它变得复杂或简单。例如:

Rails 让很多神奇的东西在幕后发生,而 Sinatra 更灵活,但需要您自己实现其中的一些东西。

controller_map = {
  'pages' => PagesController
}

post '/:controller/new' do
  c = params[:controller]
  module = controller_map[c]
  module.create_new()
  ...
end

get '/:controller/:id/show' do
  c = params[:controller]
  id = params[:id]
  module = controller_map[c]
  module.get(id)
  ...
end

如果你想要我认为你想要的东西,我总是这样做。最初对于这个方案我使用 travis-api 源作为参考,但基本上你想要做的是在 "controller" class 中扩展 Sinatra::Base 然后安装你的机架中的单个 Sinatra "controllers",如下所示:

module Endpoint
  def self.included(base)
    base.class_eval do
      set(:prefix) { "/" << name[/[^:]+$/].downcase }
    end
  end
end

class Users < Sinatra::Base
  include Endpoint

  get '/' do
    #logic here
  end

  get '/:id' do
    #logic here
  end

  post '/' do
    #logic here
  end

  patch '/:id' do
    #logic here
  end
end

class Posts < Sinatra::Base
  include Endpoint

  post '/' do
    #logic here
  end
end

然后是这样的:

class App
  require "lib/endpoints/users"
  require "lib/endpoints/posts"

  attr_reader :app

  def initialize
    @app = Rack::Builder.app do
      [Users, Posts].each do |e|
        map(e.prefix) { run(e.new) }
      end
    end
  end

  def call(env)
    app.call(env)
  end
end

您可以根据需要调整它,但想法是一样的,您将应用程序分成可组合的 Sinatra 应用程序,每个应用程序都有一个前缀,它们安装在 using Rack 下。此特定示例将为您提供以下路线:

获取“/用户”

获取'/users/:id'

post '/用户'

补丁 '/users/:id'

获取'/posts'