在多个文件上组织Sinatra“路由块”

时间:2019-03-22 02:40:01

标签: ruby sinatra

任何不平凡的Sinatra应用程序都会拥有比要添加到一个大型Sinatra :: Base后代类中更多的“路线”。假设我想把他们放在另一个班级,什么是惯用的?那另一班人是从哪儿来的?如何在主Sinatra类中“添加”它?

2 个答案:

答案 0 :(得分:4)

您只需在其他文件中重新打开课程即可。

# file_a.rb

require 'sinatra'
require_relative "./file_b.rb"

class App < Sinatra::Base
  get("/a") { "route a" }
  run!
end

# file_b.rb

class App < Sinatra::Base
  get("/b") { "route b" }
end

如果您确实想要不同的类,则可以执行以下操作,但这有点难看:

# file_a.rb

require 'sinatra'
require_relative "./file_b.rb"

class App < Sinatra::Base
  get("/a") { "route a" }
  extend B
  run!
end

# file_b.rb

module B
  def self.extended(base)
    base.class_exec do
      get("/b") { "route b" }
    end
  end
end

我很确定这两个是最简单的方法。当您查看Sinatra实际如何从诸如get之类的方法添加路由的源代码时,这非常麻烦。

我想您也可以像这样愚蠢地做某事,但我不会完全称呼它为惯用语:

# file_a.rb

require 'sinatra'

class App < Sinatra::Base
  get("/a") { "route a" }
  eval File.read("./file_b.rb")
  run!
end

# file_b.rb

get("/b") { "route b" }

答案 1 :(得分:2)

要提供另一种处理方式,您始终可以按用途进行组织,例如:

class Frontend < Sinatra::Base
  # routes here
  get "/" do #…
end


class Admin < Sinatra:Base
  # routes with a different focus here

  # You can also have things that wouldn't apply elsewhere
  # From the docs
  set(:auth) do |*roles|   # <- notice the splat here
    condition do
      unless logged_in? && roles.any? {|role| current_user.in_role? role }
        redirect "/login/", 303
      end
    end
  end

  get "/my/account/", :auth => [:user, :admin] do
    "Your Account Details"
  end

  get "/only/admin/", :auth => :admin do
    "Only admins are allowed here!"
  end
end

您甚至可以建立基类并从中继承:

module MyAmazingApp
  class Base < Sinatra::Base
    # a helper you want to share
    helpers do
      def title=nil
        # something here…
      end
    end

    # standard route (see the example from
    # the book Sinatra Up and Running)
    get '/about' do
      "this is a general app"
    end
  end

  class Frontend < Base
    get '/about' do
      "this is actually the front-end"
    end
  end

  class Admin < Base
    #…
  end
end

当然,如果需要,可以将这些类中的每一个拆分为单独的文件。一种运行它们的方法:

# config.ru

map("/") do
  run MyAmazingApp::Frontend
end

# This would provide GET /admin/my/account/
# and GET /admin/only/admin/
map("/admin") do
  MyAmazingApp::Admin
end

还有其他方法,我建议您掌握该书或查看一些博客文章(此标记的一些得分较高的人是一个很好的起点)。