db select() игнорирует условие() при использовании с соединением
Я хочу выбрать все строки из таблицы "ha", столбец доступа к которым >=0, а тип узла этого nid равен $this->ctype.
protected function queryAlter() {
if(isset($this->ctype)) {
$this->query->leftJoin('node', 'n', 'n.nid = ha.nid');
$this->query->conditions(
db_and()
->condition('ha.access', 0, '>=')
->condition('n.type', $this->ctype));
//dpr($this->query);
}
else {
$this->query->condition('ha.access', 0, '>=');
}
}
$этот->ctype установлен и равен 'ad'. И у меня нет никаких узлов с таким типом. Но db_select() игнорирует условие ('n.тип', $this->ctype) и возвращает все строки из ha (NID которых не являются типом ad).
Почему это происходит? И как вообще отлаживать db_select()?
1 answers
HearthbeatStream::$query
является объектом класса PagerActivity
, который расширяет класс SelectQuery
; это видно из кода для heartbeatstream::CreateQuery(), где значение свойства инициализируется следующей строкой.
$this->query = db_select('heartbeat_activity', 'ha')->extend('PagerActivity');
Тот факт, что PagerActivity
является расширителем SelectQuery
, означает, что каждый метод, реализованный SelectQuery
, также реализован из PagerActivity
.
SelectQuery::conditions() - это метод получения, а не метод установки. Единственный способ установить условие связанный с объектом SelectQuery
является SelectQuery::условие().
Код следует переписать следующим образом:
protected function queryAlter() {
if (isset($this->ctype)) {
$this->query->leftJoin('node', 'n', 'n.nid = ha.nid');
$this->query->condition(('ha.access', 0, '>=')
->condition('n.type', $this->ctype));
}
else {
$this->query->condition('ha.access', 0, '>=');
}
}
Для сравнения, это код, выполняемый из blog_page_user():
$query = db_select('node', 'n')->extend('PagerDefault');
$nids = $query
->fields('n', array('nid', 'sticky', 'created'))
->condition('type', 'blog')
->condition('uid', $account->uid)
->condition('status', 1)
->orderBy('sticky', 'DESC')
->orderBy('created', 'DESC')
->limit(variable_get('default_nodes_main', 10))
->addTag('node_access')
->execute()
->fetchCol();
Есть некоторые сходства с вашим кодом:
- в обоих случаях значение, возвращаемое из
db_select()
, передается методуextend()
- в обоих случаях применяется более одного условия
Используя возвращаемое значение из db_and()
с SelectQuery::condition()
не требуется, так как конструктор SelectQuery
инициализирует значение SelectQuery::$where
(используется SelectQuery::условие()) со следующим кодом:
$this->where = new DatabaseCondition('AND');
Возвращаемое значение совпадает с возвращаемым db_and().
function db_and() {
return new DatabaseCondition('AND');
}