использовать параметры при определении маршрутов в sinatra

#ruby #sinatra

#ruby #sinatra

Вопрос:

Я пытался часами и все еще не смог настроить свои маршруты так, как я хочу.

Чего я хочу добиться, так это:

http://fooo.bar/prefix1234

Я хочу записывать все, что начинается с префикса specifix.

Довольно просто:

 get "/prefix:id" do
 puts params[:id]
end
  

Но я не хочу, чтобы это был фиксированный префикс. Я хочу поместить префикс в конфигурационный файл

настройки.rb: установить :префикс, ‘pre’

 get "/#{settings.prefix}:id" do
 puts params[:id]
end
  

это не сработает (неопределенный метод `prefix’ для Sinatra::Application:Class (NoMethodError)). Я также пробовал захватывать с помощью регулярного выражения:

 before do
 @prefix = settings.prefix
end

get %r{#{@prefix}(d )} do |id| 
 puts "Params:  #{id}"
end
  

Это тоже не работает (URL-адрес не будет записан)

У кого-нибудь есть что-нибудь?

Комментарии:

1. Если в Sinatra маршруты обрабатываются так же, как в rails (сверху вниз), вы можете определить маршрут типа /* как последний, который будет соответствовать чему угодно.

2. Это также не то решение, которое я ищу, потому что я хочу обрабатывать URL-адреса с префиксом иначе, чем любой другой URL

Ответ №1:

Я смог заставить ваш пример работать почти без изменений. Это позволило мне сделать то, что вы описали:

 before do
  @prefix = "test"
end

get %r{#{@prefix}(d )} do |c|
  puts "#{@prefix} #{c}"
  erb :test, :locals => {:id => c}
end
  

Затем я запустил shotgun для проверки выходных данных и вызвал /test123. Результат был:

тест 123

Мое мнение также подтвердило, что это работает должным образом. Если проблема в том, что URL-адрес не фиксируется, возможно, вам потребуется реорганизовать вашу структуру, чтобы она больше походила:

 before do
  @prefix = "test"
end

get "/#{@prefix}/:id" do
  puts "#{@prefix} #{params[:id]}"
  erb :test, :locals => {:id => params[:id]}
end
  

Я не знаю, возможно ли последнее для вашего приложения, но если вы недостаточно конкретны в маршрутизации, вы оставляете себя открытым для частых неудачных совпадений. По моему опыту, чем более RESTful ваше приложение, тем лучше для вас, когда придет время писать операции такого типа.

В качестве альтернативы, возможно, файл YAML для хранения ваших настроек, а затем для анализа скриптом, даст вам лучшие результаты для маршрута. Например, файл YAML с таким содержимым:

 prefix: test
  

И затем вспомогательный скрипт, который анализирует это, который будет выглядеть примерно так:

 helpers do
  def config
    @config = YAML.load_file("config.yml")
  end
end
  

Затем вы могли бы заменить свой блок before этим:

 before do
  @prefix = config["prefix"]
end
  

Мои вкусы в кодировании заставляют меня склоняться к использованию метода YAML, но я думаю, что любое из этих решений должно быть жизнеспособным.

Комментарии:

1. Спасибо за предложения. Однако возможен только первый вариант, и, к сожалению, этот вариант не работает (полностью). да, если вы сделаете da, получите «/test123», URL-адрес будет записан. Но когда вы получаете «/something123», URL-адрес также будет записан. Мне кажется, что переменная @prefix всегда пуста в маршрутах

Ответ №2:

Строка / регулярное выражение генерируется сразу. Это работает:

 require 'sinatra'
set :prefix, '/foo'

get "#{settings.prefix}/bar" do
  request.path_info
end
  

Комментарии:

1. Я попробовал это, и это работает. Однако я почти уверен, что пробовал это раньше … странно

2. Хорошо, я извиняюсь, я помню, в чем была проблема: с этим кодом все мои тесты выполняются нормально, но когда я запускаю приложение, я получаю следующую ошибку: undefined method `prefix’ for Sinatra::Application:Class (NoMethodError)

3. Как указано в билете Sinatra: Вы должны установить этот параметр перед загрузкой маршрутов.