Controller/application.rb?

A quick question:

If I drop methods into an my_engine/controllers/application.rb file
should they be picked up by the app using the engine? They don’t seem to
be in some initial tests. (Tho helpers/application_helper.rb methods are
picked up ok.)

Many thanks…

The short answer - this is expected behaviour.

While that might seem intuitively that it should work, the engines
plugin won’t support that type of behaviour - essentially because
there’s nothing the name ‘application’ (which is what gets passed to
require_or_load) to indicate that this is a controller file, rather
than a library or a model - from the name alone, it could be any ruby
file.

The file ‘application_helper’ works because the Engines mechanism can
determine that it is a helper automatically, and do the code mixing
you might expect.

  • james

On 3/21/06, Lance D. [email protected] wrote:


Posted via http://www.ruby-forum.com/.


engine-developers mailing list
[email protected]
http://lists.rails-engines.org/listinfo.cgi/engine-developers-rails-engines.org

  • J *
    ~

That makes complete sense. I ask because I end up sticking in the same
code into application.rb for many apps I build (as well as other
places). So I’m creating a custom ‘general’ engine for my apps for the
obvious reasons.

One of these functions is a custom error intercept that emails us with
details of the exception. Another is a google-prefetching thwarter.
Both need to be in application.rb to work.

After some more digging around, I realized that the include line that
engines require in the application.rb and application_helper.rb load the
default module in the engines’ /lib directory. So I’ll just stick the
methods in there. (Right?)

P.S. Engines have been a lifesaver for me so far. Thanks to the
developers for all of the hard work.

James A. wrote:

The short answer - this is expected behaviour.

While that might seem intuitively that it should work, the engines
plugin won’t support that type of behaviour - essentially because
there’s nothing the name ‘application’ (which is what gets passed to
require_or_load) to indicate that this is a controller file, rather
than a library or a model - from the name alone, it could be any ruby
file.

The file ‘application_helper’ works because the Engines mechanism can
determine that it is a helper automatically, and do the code mixing
you might expect.

  • james

On 3/21/06, Lance D. [email protected] wrote:


Posted via http://www.ruby-forum.com/.


engine-developers mailing list
[email protected]
http://lists.rails-engines.org/listinfo.cgi/engine-developers-rails-engines.org

  • J *
    ~

James - for my Substruct product I’m just shoving application.rb and
application_helper.rb in my engine itself - and having people delete
those files in their /app directory.

Is this bad practice? Can you check out my engine and let me know if I
should be doing it differently?

http://dev.subimage.com/projects/substruct/wiki/InstallingSubstruct
http://www.subimage.com/files/substruct-0.054.tar.gz

Hi Seth,

I would almost certainly recommend against your approach :S By placing
application.rb within your engine, you are locking it away from the
user, and therefore preventing them from adding any of their own logic
to the ApplicationController class. If the user tries to create their
own ‘application.rb’ file in /app/controllers, your engine file will
no longer be loaded.

Current ‘best practice’ would be to wrap your methods in a module and
either have the user include this module in their
ApplicationController class, or automatically include it in
ActionController::Base by sending an :include message in your
init_engine.rb (you can’t reliably send the include to
ApplicationController because this class gets reloaded in development
mode, whilst init_engine.rb files are only evaluated at startup).

For your particular engine, you could replace your application.rb with
this module:

module SubstructApplicationController
include Substruct
include LoginSystem

def self.included(base)
  base.class_eval do
    model :user
    model :cart
    model :order_line_item
    model :order_shipping_type

    def cache
      $cache ||= SimpleCache.new 1.hour
    end
  end
end

end

… and then have the user include that in their own
ApplicationController (bear in mind that is untested code, I’m just
writing it from memory of how these things should work).

HTH,

  • james

On 3/23/06, Seth [email protected] wrote:


Posted via http://www.ruby-forum.com/.


engine-developers mailing list
[email protected]
http://lists.rails-engines.org/listinfo.cgi/engine-developers-rails-engines.org

  • J *
    ~

On 3/22/06, Lance D. [email protected] wrote:

After some more digging around, I realized that the include line that
engines require in the application.rb and application_helper.rb load the
default module in the engines’ /lib directory. So I’ll just stick the
methods in there. (Right?)

That’d be a sensible place, yeah. Just put those methods into a module
and either include it manually in your application, or send
ApplicationController (or ActionController::Base, probably) an
:include message from your init[_engine].rb to have it work
automagically.

P.S. Engines have been a lifesaver for me so far. Thanks to the
developers for all of the hard work.

Glad you’re finding them useful :slight_smile:

  • J *
    ~

I ran into this problem too when I ripped all the code from my generic
application into an engine and found the methods I had in application.rb
were missing.

The explanations in this thread make sense. The question I have is what
the
best practice is for enginizing an application.rb? When I ran generate
engine, I found that a module was created in lib with my engine’s name
and
that a subdirectory was made in lib with the name as well. The module
has a
commented out line for including files from that subdirectory. The
documentation for using an engine says to add an include line in your
application controller referencing this module, but it seems like this
module is for more universal things than just mixins for
ApplicationController, so I was thinking maybe I should create a new
module
named something like:

module EngineApplicationControllerMixins
def mymethod
end
end
and include that module in my host application’s application.rb
controller.
If I did that, I wouldn’t need to include the main module in
ApplicationController unless at some point I added code to it.

Before I go this route, I just wanted to post this message and see if I
was
missing anything that would cause me trouble down the road.

Thanks,

Daniel

“James A.” [email protected] wrote in
message
news:[email protected]