在我的GridView中,我想显示表"reply"的所有记录。该表与表"author"answers"task"有关系,并且不是每个回复都有一个任务。表"task"与另一个名为"concern"的表有关系。
以下是我的模型的关系()回复:
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'),
);
}
我的模型Reply的search()方法有以下代码:
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
));
}
在我的GridVew中,只显示带有任务的回复,并且所有过滤器都能正常工作。但我想显示所有有任务的回复和所有没有任务的回复。如果我在$criteria->数组中的search()方法中删除元素为"task"answers"task.consent"的所有reply。但是该行的筛选器来自关系"task.correct"的"Classifcation"不起作用。从逻辑上讲,我得到了错误"找不到列:1054"where子句"中的未知列"concern.classification_id"。
是否可以显示所有回复并按分类筛选这些回复?你有主意吗?
您应该了解Yii关系是如何工作的。
我想到的一件事是,当在with()属性中添加关系时,SQL生成的可能包括INNER JOIN。
这就是为什么当包含关系时,如果没有任务,你不会得到任何回复。
为了解决这个问题,您应该确保生成的SQL使用LEFT JOIN。
您可以通过使用关系的joinType属性来执行此操作:http://www.yiiframework.com/doc/api/1.1/CActiveRelation#joinType-详细
您可以在那里指定LEFT JOIN。
'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'),
这可能会奏效。但是,如果它没有像预期的那样工作,也许你需要更多的调整。
如果你想调试实际发生的事情,你可以在标准中放入一个错误的字段/表名,这会导致数据库错误,然后你可以查看执行的SQL代码,看看表是如何连接的。
建议链接:
http://www.yiiframework.com/doc/guide/1.1/en/database.arrhttp://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