1

I have Rails application with mounted Engine.

#{main_app}/config/routes.rb
mount CommentIt::Engine => "/talk", :as => 'comment_it'

And want to open engine views within main application layout.

#{main_app}/app/views/layouts/application.html.erb
<html>
  <body>
    <%= link_to "users", users_path %>
    <%= yield %>
  </body>
</html>

When accessing engine views(0.0.0.0:3000/talk) I got error 'undefined method `users_path' for #<#:0x007f9dbf0f7800>' users_path works fine in main application views. How I get route helpers from main application, when accessing Engine pages?

wildDAlex
  • 337
  • 6
  • 15

5 Answers5

4

I'm not yet sure how (un)wise this might be, but have just found the following to work for a mountable/isolated engine I'm working on:

# in app/helpers/my_engine/application_helper.rb
module MyEngine
  module ApplicationHelper
    def method_missing(method, *args, &block)
      main_app.send(method, *args, &block)
    rescue NoMethodError
      super
    end
  end
end

Thoughts?

Corey Innis
  • 464
  • 4
  • 6
  • Not a very good idea, since it breaks the isolation of the engine from the application. That means you're back to a web of dependencies instead of a nice tree. It also means you likely can't extract the engine as a gem. What's the point of using an engine if you do this? – tmandry Apr 19 '14 at 06:45
  • main_app was what I was looking for thanks. I'm having to customize stuff I get from an engine, so it's appropriate to use main_app in there, since the view lives within the app but is inserted into the engine. – Asfand Qazi Aug 26 '14 at 11:45
3

As of Rails 3.2 the only way to do this is convert your engine into a 'full' engine and not a mountable engine. In mountable engines, the engine has no knowledge of the host application and its path/url helpers are not accessible by default.

This answer explains what needs to be done, which worked for me.

The alternative is to traverse the host application's files and include the proper view/application helpers into your engine. It works, but for me it was too much of a hassle. Simply converting to a full engine did the trick.

Community
  • 1
  • 1
Joost Baaij
  • 7,188
  • 2
  • 30
  • 33
2

If you want to access engine helpers from the main application, you can use the name that you created for the app when you mounted it.

In config/routes.rb in your main application:

MyApplication::Application.routes.draw do
  mount MyEngine::Engine => "/some_engine", :as => "some_engine"
  get "/path_i_want_to_reference_from_main_app" => "some_controller#some_action"
end

Inside main application controllers/views:

some_engine.path_i_want_to_reference_from_main_app_path

So in your case you would use:

<%= link_to "users", comment_it.users_path %>

If you want to access main application helpers from an engine, try main_app.users_path

http://edgeapi.rubyonrails.org/classes/Rails/Engine.html

f1sherman
  • 433
  • 2
  • 6
  • The matter in that 'users_path' already calling from main application layout (. Rewriting main app isn't good idea, it already has thousands helpers in views. I trying to use Engine views under main application layout(with main app helpers in it). – wildDAlex May 20 '12 at 17:34
  • I see, I misunderstood your question, edited my answer to address that case as well – f1sherman May 20 '12 at 23:51
  • Thank for help. But I don't want access engine helpers from main app and not main app helpers from engine ). I want to get work main app helpers in main app layouts when layouts using in engine views. For ex. www.site.com - main app - works fine. Standalone engine with his own layout works fine too. www.site.com/talk - Engine within main app layout(see ex. above) crash with error (. – wildDAlex May 21 '12 at 07:23
  • In other words I want to work with main app helpers inside Engine without modify that helpers. Because they used in main app layout and I don't always have control over main app layouts. – wildDAlex May 21 '12 at 07:47
  • Ah, ok. I'm sorry I don't know how to do that. I would recommend taking a peek at the Rails code for how it resolves helpers, that might give you a clue on how to do this. Please share the solution if you find it. – f1sherman May 22 '12 at 11:37
2

To access main app helpers (ApplicationHelper) from engine's views I tried include this:

app/helpers/your_engine/application_helper.rb

module YourEngine
  module ApplicationHelper
    include ActionView::Helpers::ApplicationHelper
  end
end

It works, but once, when I restarted dev server, it throws me uninitialized constant ActionView::Helpers::ApplicationHelper, but I can't reproduce this exception.

EDIT

Removed this include and made this one:

lib/my_engine/engine.rb (it's inside engine)

module MyEngine
  class Engine < ::Rails::Engine
    isolate_namespace MyEngine
    config.to_prepare do
      ApplicationController.helper(ActionView::Helpers::ApplicationHelper)
    end
  end
end
Alex Fedoseev
  • 735
  • 8
  • 15
1

In my case i had MyCustomEngineController inside my gem, which inherited ApplicationController, like so:

module MyEngine
  class MyCustomEngineController < ApplicationController

#...

i changed this inheritance a little bit:

module MyEngine
  class MyCustomEngineController < ::ApplicationController

#...

(notice :: before ApplicationController)

and now all my app's helpers are available for my engine's views

okliv
  • 3,750
  • 27
  • 44