In my GridView I want to display all records of my table 'reply'. The table has relations to the tables 'author' and 'task' and not every reply has a task. The table 'task' has a relation with another table called 'concern'.
Here ist the relations() of my model Reply:
public function relations() {
return array(
'trak' => array(self::HAS_MANY, 'Task', 'reply_id', 'condition' => 'task.deleted<>1'),
'author' => array(self::BELONGS_TO, 'Author', 'author_id'),
);
}
The search() method of my model Reply has the following code:
public function search() {
$criteria = new CDbCriteria;
$criteria->with = array(
'author' => array('select' => 'id, name, role, office_id, abk', 'together' => false),
'author.office' => array('select' => 'id, name'),
'task' => array('select' => 'id, concern_id', 'together' => true),
'task.concern' => array('select' => 'id, classification_id', 'alias' => 'concern'),
);
$criteria->compare('t.id', $this->id);
$criteria->compare('t.create_time', $this->create_time);
$criteria->compare('t.create_date', $this->create_date, true);
$criteria->compare('t.office.id', $this->search_office);
$criteria->compare('t.author_id', $this->author_id);
$criteria->compare('t.rel', $this->rel, true);
$criteria->compare('t.author_id', $this->author_id);
$criteria->compare('t.lektor_id', $this->lektor_id);
$criteria->compare('t.issue_id', $this->issue_id);
$criteria->compare('t.reply_text', $this->reply_text, true);
$criteria->compare('t.deleted', $this->deleted);
if (EWMParam::getValue(EWMParam::MODUL_SCHLAGWORTE))
$criteria->compare('t.tags', $this->tags, true);
$criteria->compare('t.text_name', $this->text_name, true);
$criteria->compare('t.use_count', $this->use_count);
$criteria->compare('concern.classification_id', $this->classification_id);
$criteria->compare('t.update_time', $this->update_time);
$criteria->compare('t.update_user', $this->update_user);
$criteria->compare('t.global', $this->global);
if (EWMParam::getValue(EWMParam::MODUL_confirmationN))
$criteria->compare('t.confirmation', $this->confirmation);
$criteria->compare('t.confirmation_text', $this->confirmation_text, true);
$criteria->compare('t.use', $this->use, true);
$pagination = EWMPageSortFilterHelper::getPagination($this);
$sort = new CSort();
$sort->defaultOrder = 't.id DESC';
$sort->attributes = array(
'global' => 't.global',
'search_office' => 'office.name',
'id' => 't.id',
'text_name' => 't.text_name',
'confirmation' => 't.confirmation',
'author_id' => 'author.name',
'create_date' => 't.create_date',
'tags' => 't.tags',
'use' => 't.use',
'classification_id' => 'classification_id',
);
$sort->applyOrder($criteria);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'pagination' => $pagination,
'sort' => $sort
));
}
In my GridVew only replys with a task are displayed and all filters work fine. But I want to display all replys with a task and all replys without a task. If I delete in the search() method in the array for $criteria->with the elements 'task' and 'task.concern' all replys are displyed. But the filter for the row 'Classifcation' which comes from the relation 'task.concern' doesn't work. Logically I get the error "Column not found: 1054 Unknown column 'concern.classification_id' in 'where clause'".
Is it possible to display all replys and to filter those replys by the classification? Do you have an idea?
You should look into how Yii relations work.
One thing that comes into my mind is that when adding the relations in the with() property the SQL generated might include INNER JOINs.
That's why when having the relations included you're not getting any reply without tasks.
In order to fix that you should make sure that the SQL generated is using LEFT JOINs.
You can do that by using joinType property of a relation: http://www.yiiframework.com/doc/api/1.1/CActiveRelation#joinType-detail
And you could specify LEFT JOIN there.
'task' => array('select' => 'id, concern_id', 'together' => true, 'joinType'=>'LEFT JOIN'),
'task.concern' => array('select' => 'id, classification_id', 'alias' => 'concern', 'together' => true, 'joinType'=>'LEFT JOIN'),
That might do the trick. But maybe you need some more tweaking if it is not working just as expected.
If you want to debug what is actually happening, you could put a bad field/table name inside the criteria that would result in a database error and then you can look in the SQL code that was executed and see how tables are joined.
Suggested links:
http://www.yiiframework.com/doc/guide/1.1/en/database.arr http://www.yiiframework.com/wiki/527/relational-query-lazy-loading-and-eager-loading-with-and-together/ http://www.yiiframework.com/wiki/428/drills-search-by-a-has_many-relation