How extend ActionController ?

I have some code in ApplicationController to initialize a logging system I use to help write new complex stuff and trace exactly what's going on during development. It's just a few little extra steps added to the basic Ruby logger.

I would like to move the code into something that can be enabled with a command similar to how sessions or filters are used. I can't quite figure out how to do this. I understand the basics of modules, but only half grasping how Rails is implementing this in its hierarchy.

By poking around and imitating what I am seeing, I have this so far:

module ActionController   module RequestTrace     def self.included(base)       base.extend(ClassMethods)     end

    module ClassMethods       def request_trace(status)         ..... my code .....       end     end   end end

I then add a require statement to environment.rb to load the file, but I keep getting the error that there's no such method request_trace for ApplicationController.

A few months ago I was ableto extend AR Validators with some custom ones, but the techniques I followed to do that aren't working for this case either (very similar to above w/o the self.included bit).

Currently I am using 1.2.6. Any guidance much appreciated...

-- gw

I have some code in ApplicationController to initialize a logging
system I use to help write new complex stuff and trace exactly what's going
on during development. It's just a few little extra steps added to the basic Ruby logger.

I would like to move the code into something that can be enabled
with a command similar to how sessions or filters are used. I can't quite figure out how to do this. I understand the basics of modules, but
only half grasping how Rails is implementing this in its hierarchy.

I think it would help to see more of what you've done. What you wrote
below seems reasonable enough, but you haven't shown how you're using
or exactly what errors you're getting.

Fred

Thanks for your time on this Fred...

This is a system adapted from a framework of my own in another language. There may be a more idiomatic way to do the same, but it's something I implemented right away when I started with rails as something already familiar to me in concept and usage to help get me going.

Current code (distilled to essentials):

#----- environment.rb --------

require 'init_constants'

#----- init_constants.rb --------

DISABLED = false ENABLED = 1 CHATTY = 3 VERBOSE = 5

TRACE_FILE = 'log/request_trace.log' $request_trace = DISABLED

#----- application.rb --------

class ApplicationController < ActionController::Base

   before_filter :initialize_response

def initialize_response    .....other code.....    $request_trace = ENABLED    if $request_trace      File.delete(TRACE_FILE) if FileTest::exist?(TRACE_FILE)      $request_trace = Logger.new(TRACE_FILE)      $request_trace.info("ApplicationController.initialize_response")    end    .....other code..... end

I think it would help to see more of what you've done. What you wrote below seems reasonable enough, but you haven't shown how you're using or exactly what errors you're getting.

#----- application.rb --------

class ApplicationController < ActionController::Base

  before_filter :initialize_response   request_trace :chatty

You don't seem to be actually including your RequestTrace module into
your controller at all, you've just got this module hanging around on
its own. For starters you could include your module into ApplicationController.
It's still not doing what your first example is doing (since
request_trace will only run once, when the class is loaded (in
development mode that will be on each request, but that's a red
herring - it won't happen in production). You probably want your
request_trace function to create the appropriate before_filter or
something like that. You could also use class_inheritable_accessor
instead of a global if you want different controllers to have
different settings.

Fred

I thought that's what that self.included/base.extend business was trying to do. I guess I just need to spend more time studying why the extensions to ActionController are different from the ones in ActiveRecord. Still voodoo to me.

Probably too detailed to spend time dissecting this now, but...

I'm now confused by the lack of paralellism to what I did to write custom validations. For that, I created a file called validators.rb, I "require" it in environment.rb, and it just works. No need for an include statement in my models, and it is structured like this:

module ActiveRecord    module Validations      module ClassMethods

..... lots of code .....

I think it would help to see more of what you've done. What you wrote below seems reasonable enough, but you haven't shown how you're using or exactly what errors you're getting.

#----- application.rb --------

class ApplicationController < ActionController::Base

before_filter :initialize_response request_trace :chatty

You don't seem to be actually including your RequestTrace module into your controller at all, you've just got this module hanging around on its own.

I thought that's what that self.included/base.extend business was trying to do. I guess I just need to spend more time studying why the extensions to ActionController are different from the ones in ActiveRecord. Still voodoo to me.

They're not different. self.included is called when you do

class SomeClass    include SomeModule end Until you do that (or SomeClass.send :include etc...) nothing will happen (just creating the module in the 'right' namespace has no influence either.

Probably too detailed to spend time dissecting this now, but...

I'm now confused by the lack of paralellism to what I did to write custom validations. For that, I created a file called validators.rb, I "require" it in environment.rb, and it just works. No need for an include statement in my models, and it is structured like this:

The difference there is that you were adding to an existing module, which someone else had already included in the right place. Here you've got a new module, so you need to do the including.

Fred

Ah, that makes sense. And, I've come across a couple simple examples while research session timeout plugins where I see the Include is written into the init file -- which for me I added to environment.rb after my require statement, and voila, my system works.

Thanks for your tutoring... much clearer now.

-- greg