在多个文件上组织 Sinatra "routing blocks"
Organizing Sinatra "routing blocks" over multiple files
任何重要的 Sinatra 应用程序所具有的 "routes" 都将超过人们想要放入一个大 Sinatra::Base 后代 class 的数量。假设我想将它们放在另一个 class 中,惯用语是什么?另一个 class 是什么人的后代?我如何 "include" 它在主 Sinatra class 中?
您可以在不同的文件中重新打开 class。
# 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
如果你真的想要不同的 classes 你可以这样做,但它有点难看:
# 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" }
要提供另一种做事方式,您可以随时按用途组织它们,例如:
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
您甚至可以设置一个基础 class 并从中继承:
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
当然,如果您愿意,这些 class 中的每一个都可以拆分成单独的文件。 运行 他们的一种方法:
# 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
还有其他方法,我建议您拿到那本书或查看一些博客文章(该标签的一些高分者是一个很好的起点)。
任何重要的 Sinatra 应用程序所具有的 "routes" 都将超过人们想要放入一个大 Sinatra::Base 后代 class 的数量。假设我想将它们放在另一个 class 中,惯用语是什么?另一个 class 是什么人的后代?我如何 "include" 它在主 Sinatra class 中?
您可以在不同的文件中重新打开 class。
# 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
如果你真的想要不同的 classes 你可以这样做,但它有点难看:
# 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" }
要提供另一种做事方式,您可以随时按用途组织它们,例如:
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
您甚至可以设置一个基础 class 并从中继承:
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
当然,如果您愿意,这些 class 中的每一个都可以拆分成单独的文件。 运行 他们的一种方法:
# 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
还有其他方法,我建议您拿到那本书或查看一些博客文章(该标签的一些高分者是一个很好的起点)。