zen of coding

Can we talk enough about requestAction()?

Apparently not…

And I do mean that in a good way.

You know, this topic has been brought up a number of times before, but a recent post on google group, inspired me to do some copy/pasting.

First, I think, Martin Westin did an excellent job of explaining the basis of the disrespect for the usage of requestAction()

(I’m quoting him without permission and I hope that he doesn’t come looking for me to kick my ass)

requestAction() is a bit seductive. It can look like a simple solution
to a lot of things but the problem (that you notice later on) is that
is has a high “cost” in the processing overhead and in that you don’t
improve your design instead of using the “quick fix”.

When requestAction() is called you are effectively making a new
request more or less as you would by refreshing the browser. You are
starting up the router and dispatcher again. You are instantiating a
new controller, loading new Models, querying the database. And, worst
of all as I understand it, you are often doing a full render of an
extra View. All this results in a very costly feature.

There are times when requestAction is a good tool (the only tool?) but
they are quite few. But without knowing your application I can’t say
if you have a justified situation or not. I always feel dutifully
ashamed each time i use this feature which forces me to think if I
can’t get around my problem some other way :)

In my current project I actually have a few but in those cases doing
without it is too complicated for my taste and in only one instance is
the processing overhead an issue.

Then I decided to chime in with a coupe of alternatives…

…but just to add a little… in terms of good practice… think about the usage of requestAction()

1. Are you getting some data from another model and returning it to the current controller?

In that case you are better off doing:

$myData = $this->CurrentModel->SomeOtherModel->getMyData();

You are doing two important things here. First, you are not using requestAction() :)
Secondly, you are offloading business logic of data gathering to the model… where it really belongs.

2. Also, if you already have a controller with an action that does return some data, the legitimate question is why would one “duplicate” the code in the model as well?

Actually, you are best to move that code to the model.

Indeed, even your controller will benefit… even if you’ve got a simple find(), you can wrap it in a method inside the model such as findMeSomeCandy(); and easily call that from your controller’s find_candy()


find_candy() {
$this->set(‘candy’, $this->Candy->findMeSomeCandy());
}

Thereby also enabling to access the same method from another controller via model relation.

Even if you need it from a completely un-related model, you can do:

$candy = ClassRegistry::init(‘Candy’)->findMeSomeCandy();

Hopefully it servers as useful reminder to some… and, as always, food for thought for others.

Also, so you don’t have to dig in the comments, Mark Story (I hope you know him from such interesting endeavors as CakePHP development and an awesome site to boot), had mentioned that:

RequestAction gets a lot of bad press, even from myself. But it is a tool that is very useful if used well. With that said, it is far too easy to abuse. I’ve seen code that uses requestAction to ‘post’ data to a different controller after the view has rendered. This is one of the reasons that requestAction() gets so much bad press. The other is the additional hit on the server. Now the additional hit isn’t as bad if you use array urls as the route parsing is skipped. If your two controller actions share many of the same models, you will just be getting the models out of the ClassRegistry which isn’t as big of a hit as it is sometimes made out to be. So there are ways to squeeze additional performance out of requestAction.

P.S. Original thread that started it all: http://groups.google.com/group/cake-php/browse_thread/thread/701333f4c6654a49/4ceabc4bb9570297

  • Often it seems (to me at least, in my little world) that requestAction comes to play more with using elements, say like placing a Twitter feed in different pages of a site – that needs to talk back to a Twitter model/controller to do its thing. In this case, element/view caching helps alleviate some of the performance issues with requestAction. I agree, its use should be kept to a minimum, but if you gotta do it, do it smart.

  • @Darren

    You are absolutely right… when it comes to view/elements: requestAction() is quite helpful. Sometime ago I tried a different strategy to deal with cached model data (can’t be bothered to find a link ’cause it’s saturday).. but I’ve used it in two apps (so far) without too much hassle.

  • holooli

    first time I know that you can do:
    $myData = $this->CurrentModel->SomeOtherModel->getMyData();

    SomeOtherModel is any model? even if there is not relationship between SomeOtherModel and CurrentModel?

  • @holooli

    No, in that case it has to be related.

    That being said, take a look at the rest of the post, on what to do when models are not related ;)

  • holooli

    Yap, I’ve read your post about that, but want to make sure about the first way, thanks ;)

  • Nice, make me look at my code once again for interesting things like additional finds that I have coded in my controller.

    I know better, and this is a good reminder that the Model should be handling data access.

    I need to find some candy ;-)

  • @Rob Weaver

    I prefer to find beer on Sunday, but that’s just me :)
    Thanks for the kind feedback.

  • Another useful post! I can’t say I have ever used requestAction outside of the example Darren mentioned. Its useful for populating elements but I imagine theres just about always a way around it within your controllers.

  • @Edward Webb

    Thanks, now that I am not as lazy… here’s another post that covers how to deal with elements without requestAction() …

    http://teknoid.wordpress.com/2008/08/20/dynamic-menus-without-requestaction-in-cakephp-12/

    Hopefully it gives you something to chew on.

  • RequestAction gets a lot of bad press, even from myself. But it is a tool that is very useful if used well. With that said, it is far too easy to abuse. I’ve seen code that uses requestAction to ‘post’ data to a different controller after the view has rendered. This is one of the reasons that requestAction() gets so much bad press. The other is the additional hit on the server. Now the additional hit isn’t as bad if you use array urls as the route parsing is skipped. If your two controller actions share many of the same models, you will just be getting the models out of the ClassRegistry which isn’t as big of a hit as it is sometimes made out to be. So there are ways to squeeze additional performance out of requestAction.

  • @Mark Story

    Thank you for the insight, as always. I hope you don’t mind that I update the post with your comment as well.

  • Martin Westin

    @teknoid

    I just wanted to let you know I have no intention of “kicking your ass” :)
    If anything, I feel honored.

  • @Martin Westin

    Just when I thought my day couldn’t get any better… ;)

  • Pingback: CakePHP Digest #6 | PseudoCoder.com()

  • Pingback: Use Functions from Other Controllers While Maintaining MVC Architecture in CakePHP | Tony Thomas()

  • Rodrigo

    Thanks!

%d bloggers like this: