Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What path is a mountable engine mounted on

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".

like image 574
mxgrn Avatar asked Sep 28 '11 07:09

mxgrn


People also ask

What is Mount in Rails routes?

Mount within the Rails routes does the equivalent of a Unix mount . It actually tells the app that another application (usually a Rack application) exists on that location. It is used mostly for Rails Engines.

What is an engine in Rails?

1 What are Engines? Engines can be considered miniature applications that provide functionality to their host applications. A Rails application is actually just a "supercharged" engine, with the Rails::Application class inheriting a lot of its behavior from Rails::Engine .


2 Answers

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!

like image 75
Christoph Petschnig Avatar answered Oct 31 '22 07:10

Christoph Petschnig


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
like image 35
Koen. Avatar answered Oct 31 '22 06:10

Koen.