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?
Boontjie
(Boontjiesa)
September 17, 2012, 11:08pm
2
I think a array would be best to pass parameters like that
phtamas
(Phtamas)
September 18, 2012, 5:02am
3
For example, basic indexAction uses findAll(), another action uses findAll(‘isActive = 1’), and yet another action uses findAll(‘parentId = :pid, array(’:pid’ => $pid)).
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.
softark
(Softark)
September 18, 2012, 12:14pm
5
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);
...
}
}
softark
(Softark)
September 18, 2012, 2:59pm
7
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.
softark
(Softark)
September 18, 2012, 10:15pm
10
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.