How to "intercept" each action call?

29 views
Skip to first unread message

Lauro Caetano

unread,
May 11, 2012, 8:23:22 PM5/11/12
to rubyonra...@googlegroups.com
Hi! 

I'm a RoR beginner and I'm trying to make a gem that can "intercepts" all action from my controllers.

I would like to do something like that:

class ApplicationController < ActionController::Base
  include MyGem
end

class MyController < ApplicationController
  do_something_to :some_attribute

  def index
    respond_with(@some_attribute)
  end
end

In each call of index or other action from MyController, I want that MyGem execute "do_something_to" modifying the value of "some_attribute". Is it possible?

Thanks,
Lauro Caetano

Dheeraj Kumar

unread,
May 11, 2012, 8:27:12 PM5/11/12
to rubyonra...@googlegroups.com


Dheeraj Kumar

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

Dheeraj Kumar

unread,
May 11, 2012, 8:30:06 PM5/11/12
to rubyonra...@googlegroups.com


Dheeraj Kumar

On Saturday 12 May 2012 at 5:53 AM, Lauro Caetano wrote:

--

Dheeraj Kumar

unread,
May 11, 2012, 8:33:50 PM5/11/12
to rubyonra...@googlegroups.com


Dheeraj Kumar

On Saturday 12 May 2012 at 5:53 AM, Lauro Caetano wrote:

--

Lauro Caetano

unread,
May 11, 2012, 8:48:14 PM5/11/12
to rubyonra...@googlegroups.com
Thanks for your help Dheeraj, but I'm trying to do something like Responders.

Responders has a respond_to :html in controllers, that is used in each action call to respond_with.

The thing is: call a specific method that is located inside my gem for every action call. This method should be able to modify the attribute that was passed.

I have no idea to make this work.

2012/5/11 Dheeraj Kumar <a.dheer...@gmail.com>

Jeremy Walker

unread,
May 11, 2012, 8:50:21 PM5/11/12
to rubyonra...@googlegroups.com
On 12 May 2012 01:48, Lauro Caetano <lauroc...@gmail.com> wrote:
Thanks for your help Dheeraj, but I'm trying to do something like Responders.

Responders has a respond_to :html in controllers, that is used in each action call to respond_with.

The thing is: call a specific method that is located inside my gem for every action call. This method should be able to modify the attribute that was passed.

I have no idea to make this work.

Can you give an example of this working, please? I don't understand what you mean by "the attribute that was passed". What modifications is it going to make?

Dheeraj Kumar

unread,
May 11, 2012, 8:58:23 PM5/11/12
to rubyonra...@googlegroups.com
I don't understand your exact request, but let's see if this helps you. 

You can run filters before every action call. Inside the filter method/class, you can call your gem's methods. Also, they can modify the params hash. 

See this for two examples, one showing a filter method, and another a filter class.



Dheeraj Kumar

Lauro Caetano

unread,
May 11, 2012, 9:07:05 PM5/11/12
to rubyonra...@googlegroups.com
I'm trying to do this:

class ApplicationController < ActionController::Base
  include MyGem
end

class TasksController < ApplicationController
  injector_to :task

  def show
    respond_with(@task)
  end
end

When the action 'show' is called, the "injector_to" should inject the @task for me. 
In other words, injector_to makes "Task.find(params[id])" for me in this case.

Other example: If I have this action ->

def create
  respond_with(@task)
end

the injector_to should do the hard work, instantiating the @task and saving it.

I think that I've explained better now.

2012/5/11 Jeremy Walker <jez.w...@gmail.com>

Jeremy Walker

unread,
May 11, 2012, 9:18:43 PM5/11/12
to rubyonra...@googlegroups.com
On 12 May 2012 02:07, Lauro Caetano <lauroc...@gmail.com> wrote:
I'm trying to do this:

class ApplicationController < ActionController::Base
  include MyGem
end

class TasksController < ApplicationController
  injector_to :task

  def show
    respond_with(@task)
  end
end

OK, so you're trying to automate the default behaviour for a standard controller without using scaffolding? That makes sense.

Two methods spring to mind. 
1) A generic controller than handles the methods that other controllers inherit from. You then set the variable name and class in each child controller, maybe via overloaded methods or through your injector_to method.
2) Your gem adds injector_to to ActiveController. When called it dynamically adds the standard methods to the controller. You then patch ActiveController so rather than looking for the "show" method, it looks for "injected_show", etc, which calls the scaffold code, then calls the controller-specific "show" method if there is one. That's the nicest way of doing it from an end-user point of view. 

I actually quite like this idea. If you want some help writing them Gem, let me know offlist and I'll happily help.

Dheeraj Kumar

unread,
May 11, 2012, 9:19:45 PM5/11/12
to rubyonra...@googlegroups.com
I understand. See the link I posted, where the OP does exactly your requirement. Here's some code:

class ApplicationController < ActionController::Base
  include MyGem
end

class TasksController < ApplicationController
  before_filter :find_task

   def find_task
      @task = Task.find(params[:id])
      # Some other operation involving MyGem if you need...
   end

  def show
    respond_with(@task)
  end
end


Dheeraj Kumar

Dheeraj Kumar

unread,
May 11, 2012, 9:33:36 PM5/11/12
to rubyonra...@googlegroups.com
@Jeremy:

#1 seems to be the easiest, but #2 is the best solution. 

Here's my view of how this can work:

class TasksController < ApplicationController
    # Specify which class has the generic scaffolding methods
    scaffold :my_custom_scaffold_class
    
    # or we bundle a generic class with the gem
    scaffold

    # Overriding is possible
    def show(id)
        # instance variable is already injected by our gem
        # do something with the @task
    end
end

or even

class ApplicationController < ActionController::Base
    scaffold
end

to propagate to all controllers which inherit from ApplicationController.


Dheeraj Kumar

Lauro Caetano

unread,
May 11, 2012, 10:03:04 PM5/11/12
to rubyonra...@googlegroups.com
Thank very much for all your help =)

@Jeremy the #2 is awesome :)

@Dheeraj your point of view is really coll too!

And yes! I would like to get some help to get this gem done.

I've created a github repo at: https://github.com/laurocaetano/injector

At time, sorry for my really bad english =(

Thanks guys!


2012/5/11 Dheeraj Kumar <a.dheer...@gmail.com>
Reply all
Reply to author
Forward
0 new messages