Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Main App Helpers when overridings a Rails Engine View/Layout

I have created a simple Rails Engine to provide some general functionality(photo gallery) to an application. I want to be able to override the standard _header partial so that the menu for the gallery matches that of my main application. In my header view I call a helper that is part of application_helpers (main app), but I keep getting "undefined method" errors. From what I can tell the main app application_helpers are not being included (obviously) when I override the engines application layout or its partials.

So my question is, how do I override an engine view in the main application, and get access to the main application helper methods? I would still need access to the engine helpers as well as not to screw up the engine functionality.

Do I need to override the controllers as well? seem like a lot just to get some helpers.

Thanks

Rails 3.1.3

like image 831
utahtwo Avatar asked Feb 10 '12 17:02

utahtwo


4 Answers

check out this blog post: http://www.candland.net/2012/04/17/rails-routes-used-in-an-isolated-engine/ The author adds a method_missing definition to the application helper in order to access the parent application's helpers.

/config/initializers/blogit.rb

module Blogit     module ApplicationHelper       def method_missing method, *args, &block         puts "LOOKING FOR ROUTES #{method}"         if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')           if main_app.respond_to?(method)             main_app.send(method, *args)           else             super           end         else           super         end       end        def respond_to?(method)         if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')           if main_app.respond_to?(method)             true           else             super           end         else           super         end       end     end   end 
like image 95
Sam Backus Avatar answered Sep 27 '22 00:09

Sam Backus


Try including the main app helper methods. For instance:

class MyEngineClass   include ApplicationHelper    #... end 

You may possibly need to require the file first, though I would expect Rails to correctly find it in this case.

Once ApplicationHelper is included, you should be able to directly use those helpers in the controller.

It also looks like you can call ClassName.helper("application") for a lot of Rails classes -- not sure if that will work here.

like image 20
Noah Gibbs Avatar answered Sep 27 '22 00:09

Noah Gibbs


try creating a helper in your application with the same name of the helper in your engine in order to override engine helper methods.

I found this discussion particularly insightful. There are also some interesting ideas in the Rails Engine API docs under Isolated engine helpers.

like image 33
Patrick Klingemann Avatar answered Sep 26 '22 00:09

Patrick Klingemann


Engines are supposed to be independent from the main app, that is why you can't access its helpers from the Engine.

However, there are hack-ish ways for giving your engine access to the helpers of the main app. This is how I did it:

# In the main app
# initializers/share_helpers_path_with_engine.rb
PhotoGallery::Engine.class_eval do
  paths["app/helpers"] << File.join(File.dirname(__FILE__), '../..', 'app/helpers')
end

You need of course to change PhotoGallery to the actual name of your engine class.

Feel free to take a look at the Engines documentation (section about the paths): http://edgeapi.rubyonrails.org/classes/Rails/Engine.html

like image 31
midu Avatar answered Sep 24 '22 00:09

midu