Sinatra:将嵌套路由传递给控制器

时间:2017-11-23 12:00:34

标签: ruby sinatra

我尝试用Sinatra实现的目标是,我认为这个问题相当简单。我有一堆控制器(来自Rails世界),我从 config.ru 运行它们,看起来像:

require 'sinatra/base'
require './app'

# require all the parts needed
Dir.glob('./{controllers,helpers,models}/*.rb').each { |file| require file }

# start the server via Rack map method which binds route to Sinatra app
map('/') { run ApplicationController }
map('/') { run AuthenticationController }
map('/customers') { run CustomerController }
map('/contact_us') { run ContactUsController }

他们是ApplicationController的子类(App< Sinatra :: Base的子类),然后我在这里做了类似的事情

  get '/:id/home' do
    erb :'/customers/home'
  end

我想要做的是能够使用ID为 / customers /:id / contacts 的嵌套路由,而无需复制控制器中的整个路径。我不能用map做这个,使用 namespace 也似乎不是解决这个问题的方法。我建议如何更好地构建它以实现这一目标。

感谢。

1 个答案:

答案 0 :(得分:1)

你应该能够做到这一点(注意:你应该use每个额外的控制器而不是运行它们。

run ApplicationController
use AuthenticationController
use CustomerController
use ContactUsController

然后在每个控制器中,您需要继承ApplicationController类,如下所示:

class AuthenticationController < ApplicationController
    get "/" do
        erb :index
    end
end


加成:

您甚至可以将其添加到config.ru,以避免为所有控制器键入use

Dir[File.join(File.dirname(__FILE__), "app/controllers", "*.rb")].collect {|file| File.basename(file).split(".")[0] }.reject {|file| file == "application_controller" }.each do |file|
  string_class_name = file.split('_').collect { |w| w.capitalize }.join
  class_name = Object.const_get(string_class_name)
  use class_name
end