Thanks for the replies. So I understand why I can't create a class with the exact same name in local app -- if I do it will entirely replace the one in the plugin/gem. I understnad that.
What I don't understand is why I can't manage to selectively over-ride view helpers from the plugin in the local app. Why the plugin's helper gets loaded such that it's first in the call chain, and any application view helper modules are further 'up' in the call chain, so can't over-ride it. Scrambling through the Rails code trying to figure it out, it is very confusing code, jumping all over the place, to load helpers. (put a "def self.included ; debugger ; end " in my various helper modules, in which i can raise an exception in the debugger to see a back trace, in order to try to begin understanding what Rails is doing). But it looks like helpers with the 'default' name (WidgetHelper for WidgetController) get loaded through a somewhat different path through rails, and that could be part of it. Perhaps if I give my helper a different name, and then manually do a "helper OtherNameWidgetHelper" in the controller (defined in the gem), that would allow the applications' helpers to over-ride it. I may try that. I am not happy with solutions that _require_ something to be generated into the local app for default behavior. The nice thing about the current design (if it worked), is that if you _don't_ want to over- ride a helper from the gem, you don't need anything in the local app, not a stub file or an 'include' in your ApplicationHelper etc. You only need to do something if you DO want to over-ride. (In this case, wanting to over-ride will be a rare thing). I also not happy with solutions that require the local app to add something to ApplicationHelper -- because it makes the helper available for ALL controllers, not just the one it belongs to. Rails seems to keep switching back and forth on whether "helper :all" is a default, or is even mandatory behavior you can't change -- I'm not sure what Rails 3.0.8 or Rails 3.1 are doing here, but it gets confusing, keeps switching, and I don't want to assume this behavior, or require the app to use this behavior in a current or future version of Rails that may not otherwise require it. That is, I don't want to force the user to include the gem-supplied helper module in _every_ controller (via ApplicationHelper), just in order to make it over- rideable. Hey Ryan, you say many other people have thoughts on this -- I've been googling like crazy to find em, but haven't found much that is clearly relevant to Rails 3.0 final and beyond -- if you have any URLs to good places to see other ideas relevant in current rails, please do share! Jonathan On Jun 19, 12:38 pm, Everton Moreth <[email protected]> wrote: > Your application will lazy load your ApplicationHelper. Wich means that when > you call your engine Helper, the app will look through all folders until it > finds one named AdvancedHelper. > When you create your own AdvancedHelper it will find it on the app and then > never lookup at the engine. So, nothing gets loaded (consequently nothing > gets overrided) from your gem. > > You could inherit from the engine Helper or even include it as Ryan said. > But you'll need to namespace it. > Or you could force the engine load on initialization of the app, and then > reopen the class on the app. But I would go for including it. > > Everton > > > > > > > > On Sat, Jun 18, 2011 at 8:47 PM, Ryan Bigg <[email protected]> wrote: > > I would have this helper module inside a namespace within the engine, > > which will allow people to have a similarly named one in the application. In > > the application's helper, then I would just include the engine's one, the > > process of which would make those methods available in the application > > without overriding the engine. After that, it's just a matter of overriding > > the methods underneath the `include` statement. > > > I don't claim that this is the canonical way to do it, but it is a clean > > way. Maybe other people have thoughts as well on this. > > > On Saturday, 18 June 2011 at 7:00 AM, Jonathan Rochkind wrote: > > > This one is driving me crazy, appreciate it VERY much if someone can > > even give me some hints at where to look in Rails source code to > > understand/debug what's going on, I'm getting lost trying to look > > through it. > > > Rails 3.0.8. I have an engine(gem). > > > It provides a controller at app/controllers/advanced_controller.rb, > > and a corresonding helper at app/helpers/advanced_helper.rb. (And some > > views of course). > > > So far so good, the controller/helper/views are just automatically > > available in the application using the gem, great. > > > But I want to let the local application selective over-ride helper > > methods from AdvancedHelper in the engine (and ideally be able to call > > 'super'). That's a pretty reasonable thing to want to allow, right, a > > perfectly reasonable (and I'd think common) design? > > > Problem is I can't get it to work. Let's say there's a method > > #do_something in the engine's app/helpers/advanced_helper.rb. > > > * If the local app provides an app/helpers/advanced_helper.rb, > > then it completely replaces the one from the engine, the one from the > > engine isn't loaded at all. (So it has none of it's methods, even > > though we just wanted to over-ride one of em). Okay, this isn't > > actually TOO unexpected. > > > * So I provide a helper called, say > > local_advanced_helper.rb(LocalAdvancedHelper) in my local app/helpers. > > It DOES load. If it implements a #new_method_name, that helper is of > > course available in views (including the engine's views, as it > > happens). However, if it tries to over-ride the engine's > > #do_something ... the local do_something is never called. > > > The engine's helper seems to be 'included' in the module providing > > helper methods to views earlier in the call chain (later in the > > 'include' order) then my local helpers. So there's no way for local > > helpers to over-ride helpers from the engine. (The engine could > > theoretically call 'super' to call 'up' to the local view helper with > > the same name, but of course that makes little sense, that kind of > > dependency is probably seldom appropriate). The ones from the engine > > are always first in the call chain, before any view helper modules in > > local app. > > > Can anyone shed any light on what's going on? Including pointing me to > > the relevant parts of Rails code? Or suggesting any way I can get > > this kind of design (local app can over-ride view helpers provided by > > Engine) to work? Or tell me if this is a bug, or by design, or > > neither (just didn't consider use case), or what? > > > Any feedback much appreciated. I've been going crazy trying to figure > > this out for hours now. Also posted (in slightly different words) at > >http://stackoverflow.com/questions/6380064/rails3-engine-helper-over-... > > > Jonathan > > > -- > > You received this message because you are subscribed to the Google Groups > > "Ruby on Rails: Core" group. > > To post to this group, send email to [email protected]. > > To unsubscribe from this group, send email to > > [email protected]. > > For more options, visit this group at > >http://groups.google.com/group/rubyonrails-core?hl=en. > > > -- > > You received this message because you are subscribed to the Google Groups > > "Ruby on Rails: Core" group. > > To post to this group, send email to [email protected]. > > To unsubscribe from this group, send email to > > [email protected]. > > For more options, visit this group at > >http://groups.google.com/group/rubyonrails-core?hl=en. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
