How to map routes to controllers in Sinatra?

对着背影说爱祢 提交于 2019-12-23 02:05:10

问题


I'd like to create a simple experimental MVC framework using Sinatra.

I'd like to define resources by name "pages" for example should resolve to:

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

as WELL as map to app/controllers/PagesController.rb with corresponding get('/') to be responsible for the index, post('/pages/create') be responsible for creation, etc.

Trouble is even after reading the official documentation I'm terribly confused. I imagine I need to use non-classic Sinatra model for this, but could anyone point me in the right direction?

Thank you


回答1:


If you want what I think you're wanting, I do this all the time. Initially for this scheme I used the travis-api source as a reference, but essentially what you want to do is extend Sinatra::Base in a "controller" class and then mount up your individual Sinatra "controllers" in rack, something like this:

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

and then something like this:

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

You can adjust this to whatever you need, but the idea is the same, you separate your app into composable Sinatra applications that each have a prefix that they are mounted under using Rack. This particular example will give you routes for:

get '/users'

get '/users/:id'

post '/users'

patch '/users/:id'

get '/posts'




回答2:


I'll give you a very simple example here:

Create a file controller.rb

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

Next create a views directory in the same folder as teh controller, and create a file named pages.html.erb

This is the corresponding view to your previously created controller action.

Here, you can type something like:

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

Restart your server, visit localhost:PORT/pages and you will see a list of all your page titles.

You can check out this link for a simple sinatra tutorial - http://code.tutsplus.com/tutorials/singing-with-sinatra--net-18965




回答3:


You can make this as complicated or as simple as you need. For example:

Rails makes a lot of magic happen under the hood, whereas Sinatra is more flexible at the cost of requiring you to implement some of this stuff yourself.

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


来源:https://stackoverflow.com/questions/30421971/how-to-map-routes-to-controllers-in-sinatra

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!