views:

3469

answers:

3

In a controller, what is the most appropriate way to call the action of another controller and also pass an array as parameter?

I know that you can use requestAction to call actions within other controllers. But is it possible to pass arrays as parameters using request action?

And no, I do not want to put the action in the App Controller. So that is not a solution for me.

The only other way I know is to load the other controller as explained in: http://book.cakephp.org/view/531/Importing-Controllers-Models-Components-Behaviors-

But is there an easier way to just call the other controllers action while passing an array as parameter?

I am new to cakePHP so any suggestion is appreciated. Thanks.

+1  A: 

As of CakePHP 1.2.5, you should be able to pass various parameter types through the second parameter in requestAction(). e.g.:

$this->requestAction('/users/view', array('pass' => array('123')));

Then in the UsersController:

function view($id) {
    echo $id; // should echo 123 I believe, otherwise try $this->params['pass'].
}

Instead of using 'pass' above, you can alternatively try 'form' and 'named' to pass form/named parameters respectively.

Matt Huggins
Great! wasn't sure whether I can do that. Will try it. Thank you.
Vicer
i can confirm that this works
Mikelangelo
+4  A: 

I would not advice to use the method requestAction but rather import, and instantiate the needed controller.

CakePHP doc says about requestAction that:

"It is rarely appropriate to use in a controller or model"

http://book.cakephp.org/view/434/requestAction

Once you imported and loaded the controller you can call any method of this controller with its parameters.

<?php
  //Import controller
  App::import('Controller', 'Posts');

  class CommentsController extends AppController {
    //Instantiation
    $Posts = new PostsController;
    //Load model, components...
    $Posts->constructClasses();

    function index($passArray = array(1,2,3)) {
      //Call a method from PostsController with parameter
      $Posts->doSomething($passArray);
    }
  }
?>
Schaoulli
thanks for your reply. yes I have heard that rumor about requestAction. wonder why it's not encouraged. Anyway, 'Import' is an alternate solution, thanks.
Vicer
I agree, this is best, I had been using requestaction but it quickly shows why its not good, if you need to pass in a string that contains anything but basic text it won't work right, since its using the url method so it can't have special characters and if you use "/" in a string htis will break it into separate variables
Rick
+1  A: 

Would it be appropriate for you to move the logic from the second controller into it's model, then do something like this in your first controller's action:

$var = ClassRegistry::init('SecondModel')->myMethod($array);
$this->set(compact('var'));

then in the view for the first controller's action, you can use that data.

I always try to keep controller methods to actions you can hit through the browser, put as much logic in my models, call foreign model methods from controllers actions that need data from models that aren't the model for that controller, then use that data in my views, and if it's data that is viewed frequently, I create an element for it.

neilcrookes
good suggestion. I have heard somethings about separating logic from controller to model before. but still not clear about that concept. maybe as I gain more experience with cake, I will get a clearer picture. Thanks for your help.
Vicer
Neil has the right idea. Controllers are intended to handle and delegate incoming requests. Business logic, or code that does stuff should primarily be in your models.
Mark Story
I don't believe this is correct, models are for database access rules, the controllers handle everything else, the bulk of an application would be in the controller, in most cases.. I don't know what you mean by "code that does stuff".. anyways, the best practice IMO is to make code re-use a priority, so ideally a lot of stuff should be placed in controller componenets, the model is only used for stuff like data validation, etc, and in these cases should usually also be made into components (within the model folder) for re-use of these as well
Rick
I disagree. Models should be fat, controllers skinny. As much logic should be put in models as possible. All your controller should do is process the request, deal with sessions, call model methods, set data for the view and handle userflow etc. If you find you are doing these things the same in lots of controllers, then create a component for it. BTW, did you know the comment you commented on, was written by the one of the lead developers of CakePHP?
neilcrookes