Pass Criteria To External Action

Hi guys.

I have a lot of repetitive actions, like actionIndex, so I want to put it into external class (CAction).

But sometimes these actions use additional conditions for querying the DB.

For example, basic indexAction uses findAll(), another action uses findAll(‘isActive = 1’), and yet another action uses findAll(‘parentId = :pid, array(’:pid’ => $pid)).

So here’s the question. What would be the best way to do it, taking into account that db criteria can depend on action get params?

I think a array would be best to pass parameters like that

Don’t over-abstract. Having similar looking code fragments doesn’t necessarily mean code repetition and you might end up with a very complicated and hard to maintain solution.

In my case it actually is code repetition.

The only piece that differs is the simple condition used for list filtering.

I second phtamas, in general.

I would be satisfied just by sharing the view script.

But, do you mean that your multiple actionIndexes share the same model but with slightly different filtering conditions? Then I guess passing the scope to the action may work.

Well, no.

The model is also different, but I can pass its name via params or guess it from controller’s name, like this:

Action:




class IndexAction extends CAction

{

    public $model;


    public function run() {

        $controller = $this->getController();

        $modelClass = $this->model ? $this->model : ucfirst($controller->getId());

        ...

    }

}



Controller:




class MyController extends CController {


    public function actions() {

        return array(

            'index' => array(

                'class' => 'application.controllers.json.IndexAction',

                'model' => 'FancyModel',

            ),

            ...

        );

    }


}



I can also pass simple conditions this way, but I’m a little confused about action named params.

For example, I can do something like this:


class IndexAction extends CAction

{

	public $model;

	public $criteria;


	public function run() {

		$controller = $this->getController();

		$modelClass = $this->model ? $this->model : ucfirst($controller->getId());


		...


		$criteria = new CDbCriteria;

		$criteria->addCondition(...); // some default conditions


		if ($this->criteria) {

			$criteria->mergeWith($this->criteria);

		}


                $criteria->params = <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/huh.gif' class='bbc_emoticon' alt='???' />?<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/huh.gif' class='bbc_emoticon' alt='???' />; // 


		$list = $modelInstance->findAll($criteria);


		...


	}

}

I see.

Isn’t this enough, when $this->criteia has params in it?

It would be enough if only I can get action params BEFORE the criteria is created.

Here’s the example:


public function actions() {

    $criteria = new CDbCriteria;

    $criteria->with = ...;

    $criteria->addCondition('parentId = :pid');

    $criteria->params[':pid'] = <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/huh.gif' class='bbc_emoticon' alt='???' />; // Named parameter required


    return array(

        'index' => array(

            'class' => 'application.controllers.external.IndexAction',

            'model' => 'FancyModel',

            'criteria' => $criteria,

        ),

        ...

    );

}

Seems like I can’t get named params of action inside public function actions.

Hmmm, but I can pass an array of conditions and use actionParams to construct criteria in the action class.

I think the problem is solved.

Um, I don’t get it.

Could you show us your final solution?

Not done yet, but will submit it once completed.