9

I need to know, from inside of a layout of a mountable engine, what path it's currently being mounted on. What would be the way to do it?

E.g. my routes.rb contains the following line:

  mount BackendCore::Engine => "/backend"

From inside of the BackendCore, I need the access to the value of "/backend".

tshepang
  • 12,111
  • 21
  • 91
  • 136
mxgrn
  • 1,733
  • 16
  • 20
  • possible duplicate of [Reverse rails routing: find the the action name from the URL](http://stackoverflow.com/questions/3481731/reverse-rails-routing-find-the-the-action-name-from-the-url) – Ben Lee Sep 28 '11 at 07:23
  • 1
    The link you provide does not help much, as it has no references to engines, although it gives a direction to search in. – mxgrn Sep 28 '11 at 07:51

4 Answers4

10

If the engine is mouted :as => a different name, querying named_routes will not be sufficient. This monkey patch will do:

class Rails::Engine
  def self.mounted_path
    route = Rails.application.routes.routes.detect do |route|
      route.app == self
    end
    route && route.path
  end
end

Now call mounted_path on the engine:

BackendCore::Engine.mounted_path => "/backend"

Note: be careful, in production mode, the classes in your engine are evaluated before the routes of the main app are loaded. Calling this method in class macros might not work!

Christoph Petschnig
  • 4,047
  • 1
  • 37
  • 46
8

UPDATE: this probably applies to Rails 3 only!

I found the solution:

Rails.application.routes.named_routes[:backend_core].path #=> "/backend"
mxgrn
  • 1,733
  • 16
  • 20
3

Evaluating the routes to get the mount path can give unexpected results when engines are mounted inside other engines.

When you take a look at https://github.com/rails/rails/pull/5008 you can read the comment by Jose Valim:

Also, an engine can be mounted inside another engine, so it is unlikely that this will give you the proper result. The best option is probably to have a configuration option where the developer will set the path.

For consistent results, I'm now using an accessor on the engine.

For example:

# APP/initializers/backend_core_engine.rb
BackendCore::Engine.mount_path = "/backend"

# APP/config/routes.rb
mount BackendCore::Engine => BackendCore::Engine.mount_path

# ENGINE/backend_core/lib/engine.rb
module BackendCore
  class Engine < ::Rails::Engine
    cattr_accessor :mount_path
  end
end
Koen.
  • 25,449
  • 7
  • 83
  • 78
0

You could simply use the following code to tell what path engine is mount to inside an engine controller/view:

env["SCRIPT_NAME"] # => "/backend"
Tian Chen
  • 493
  • 4
  • 15
  • It shouldn't be possible to get a downvote with no explanation. How can I trust if that downvote makes sense or not? – a.barbieri Nov 30 '17 at 07:33