Организация Sinatra "блоков маршрутизации" по нескольким файлам - PullRequest
0 голосов
/ 22 марта 2019

Любое нетривиальное приложение Sinatra будет иметь больше «маршрутов», чем хотелось бы поместить в один большой класс-потомок Sinatra :: Base. Скажем, я хотел поместить их в другой класс, что такое идиоматизм? От чего произошел этот другой класс? Как мне «включить» его в основной класс Синатры?

Ответы [ 2 ]

4 голосов
/ 22 марта 2019

Вы можете просто заново открыть класс в разных файлах.

# 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" }
2 голосов
/ 08 апреля 2019

Чтобы дать другой способ действий, вы всегда можете организовать их по их использованию, например:

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

Есть и другие способы, я предлагаю вам достать эту книгу или почитать несколько постов в блоге (некоторые из лучших бомбардиров для этого тега - хорошее место для начала).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...