如何将路由映射到 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'
我想使用 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'