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

5

24

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

Kenwee answered 10/2, 2012 at 17:35 Comment(2)
Have you tried main_app.your_helper_method?Quinta
Try the method outlined in this question if you don't want to override the controllersGarges
C
3

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
Chimb answered 18/10, 2013 at 15:16 Comment(2)
This just adds _path and _url helpers which is all I needed. There is a better solution though. Add helper Rails.application.routes.url_helpers to your engine's ApplicationController. See my comments on the linked blog post.Keary
For OP, you could probably use the same technique for with helper Rails.application.helpers.Keary
B
2

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.

Blackington answered 12/9, 2012 at 4:27 Comment(0)
A
1

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.

Apolitical answered 13/3, 2012 at 20:33 Comment(1)
The Rails Engine API docs helped me figure out a good solution for url_helpers! Thanks.Keary
I
1

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

Irrelevant answered 3/10, 2012 at 3:18 Comment(0)
F
0

Disclaimer: I've only used this solution in Rails 3.2 engines.

If, in your engine you have a standard header partial vendor/gems/my_gallery_engine/app/views/application/_header.html.erb.

Then, override it in your main app by creating a customized partial app/views/application/_header.html.erb.

The override works because Rails' view template search path (by default) starts with the main apps' app/views directory, and then searches through engines' app/views in load order.

All of your main app's Helpers will be available in the partial.

Frenchy answered 1/10, 2012 at 3:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.