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
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
You could simply use the following code to tell what path engine is mount to inside an engine controller/view:
env["SCRIPT_NAME"] # => "/backend"
UPDATE: this probably applies to Rails 3 only!
I found the solution:
Rails.application.routes.named_routes[:backend_core].path #=> "/backend"
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!