What path is a mountable engine mounted on
I need to know, from in开发者_如何学编程side 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".
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!
UPDATE: this probably applies to Rails 3 only!
I found the solution:
Rails.application.routes.named_routes[:backend_core].path #=> "/backend"
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"
精彩评论