【问题标题】:Organizing Sinatra "routing blocks" over multiple files在多个文件上组织 Sinatra“路由块”
【发布时间】:2019-08-12 23:57:20
【问题描述】:

任何非平凡的 Sinatra 应用程序都将拥有比一个大的 Sinatra::Base 后代类更多的“路线”。假设我想把他们放在另一个班级,什么是惯用的?其他阶级是什么人的后代?如何在 Sinatra 主类中“包含”它?

【问题讨论】:

    标签: ruby sinatra


    【解决方案1】:

    要提供另一种做事方式,您可以随时按用途对其进行组织,例如:

    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
    

    还有其他方法,我建议你掌握那本书或查看一些博客文章(这个标签的一些高分者是一个很好的起点)。

    【讨论】:

      【解决方案2】:

      您可以在不同的文件中重新打开课程。

      # 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" }
      

      【讨论】:

        猜你喜欢
        • 2013-02-24
        • 1970-01-01
        • 2016-10-27
        • 1970-01-01
        • 2011-06-03
        • 1970-01-01
        • 2012-02-04
        • 1970-01-01
        • 2014-01-13
        相关资源
        最近更新 更多