bogdanrada
5/21/2015 - 2:35 PM

recognize_path.rb

  module RecognizePath
    def recognize_path(path, options)
      recognized_path = Rails.application.routes.recognize_path(path, options)

      # We have a route that catches everything and sends it to 'errors#not_found', you might
      # need to rescue ActionController::RoutingError
      return recognized_path unless recognized_path.slice(:controller, :action) == {controller: 'errors', action: 'not_found'}

      # The main app didn't recognize the path, try the engines...
      Rails.application.railties.engines.each do |engine|

        # Find the route to the engine, e.g. '/blog' -> Blog::Engine (a.k.a. "mount")
        engine_route = Rails.application.routes.routes.find { |r| r.app.to_s == engine.class.to_s }
        next unless engine_route

        # The engine won't recognize the "mount", so strip it off the path,
        # e.g. '/blog/posts/new'.gsub(%r(^/blog), '') #=> '/posts/new', which will be recognized by the engine
        path_for_engine = path.gsub(%r(^#{engine_route.path.spec.to_s}), '')
        begin
          recognized_path = engine.routes.recognize_path(path_for_engine, options)
        rescue ActionController::RoutingError => e
          Rails.logger.debug "[#{engine}] ActionController::RoutingError: #{e.message}"
        end
      end

      recognized_path
    end
  end