@Saurabh Я добавил свои выводы

я Rails: '~> 4.2.7.1'

Версия Spree: '3.1.1'

TlDr: Как мне получить маршрут как/api/products/:id или контроллер и действие этого маршрута в промежуточном программном обеспечении приложения Rails 4.

Подробности:

Я добавляю промежуточное программное обеспечение в моем приложении rails, которое похоже на gemscout_statsd_rack, Это добавляет следующеепромежуточный слой в приложение rails для отправки метрик через statsd:

def call(env)
  (status, headers, body), response_time = call_with_timing(env)
  statsd.timing("#{env['REQUEST_PATH']}.response", response_time)
  statsd.increment("#{env['REQUEST_PATH']}.response_codes.#{status.to_s.gsub(/\d{2}$/,'xx')}")
  # Rack response
  [status, headers, body]
rescue Exception => exception
  statsd.increment("#{env['REQUEST_PATH']}.response_codes.5xx")
  raise
end

def call_with_timing(env)
  start = Time.now
  result = @app.call(env)
  [result, ((Time.now - start) * 1000).round]
end

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

Я попробовал подход описанныйВот, который говоритenv['PATH_INFO'] может предоставить путь, который он делает, но он дает URL-параметры следующим образом:/api/products/4 но я хочу/api/products/:id так как моя цель состоит в том, чтобы отслеживать производительность/api/products/:id API.

env['REQUEST_PATH'] а такжеenv['REQUEST_URI'] также дает тот же ответ.

Я попробовал ответ при условииВот а такжеВот:

Rails.application.routes.router.recognize({"path_info" => env['PATH_INFO']})

или как это

Rails.application.routes.router.recognize(env['PATH_INFO'])

Но это дало следующую ошибку:

NoMethodError (неопределенный методpath_info' for {"path_info"=>"/api/v1/products/4"}:Hash):<br>vendor/bundle/gems/actionpack-4.2.7.1/lib/action_dispatch/journey/router.rb:100:infind_routes'
продавец / пакет / драгоценные камни / actionpack-4.2.7.1 / Библиотека / action_dispatch / путешествие / router.rb: 59: вrecognize'<br>vendor/bundle/gems/scout_statsd_rack-0.1.7/lib/scout_statsd_rack.rb:27:inвызов'

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

Редактировать # 1

Вы можете увидеть образец репоВот, с кодом рельсов промежуточного программного обеспеченияВотНастройку этого можно сделать как указано вПРОЧТИ МЕНЯ и чем может быть поражен этот API:http://localhost:3000/api/v1/products/1.

Редактировать № 2

Я попробовал подход, данный @ MichałMłoźniak, как показано ниже:

def call(env)
  (status, headers, body), response_time = call_with_timing(env)
  request = ActionDispatch::Request.new(env)
  request = Rack::Request.new("PATH_INFO" => env['REQUEST_PATH'], "REQUEST_METHOD" => env["REQUEST_METHOD"])
  Rails.application.routes.router.recognize(request) { |route, params|
    puts "I am here"
     puts params.inspect
     puts route.inspect
   }

Но я получил следующий ответ:

I am here 
{}
#<ActionDispatch::Journey::Route:0x007fa1833ac628 @name="spree", @app=#<ActionDispatch::Routing::Mapper::Constraints:0x007fa1833ace70 @dispatcher=false, @app=Spree::Core::Engine, @constraints=[]>, @path=#<ActionDispatch::Journey::Path::Pattern:0x007fa1833acc90 @spec=#<ActionDispatch::Journey::Nodes::Slash:0x007fa1833ad230 @left="/", @memo=nil>, @requirements={}, @separators="/.?", @anchored=false, @names=[], @optional_names=[], @required_names=[], @re=/\A\//, @offsets=[0]>, @constraints={:required_defaults=>[]}, @defaults={}, @required_defaults=nil, @required_parts=[], @parts=[], @decorated_,ast=nil, @precedence=1, @path_formatter=#<ActionDispatch::Journey::Format:0x007fa1833ac588 @parts=["/"], @children=[], @parameters=[]>>

Я также подтолкнул измененияВот.

Ответы на вопрос(1)

Ваш ответ на вопрос