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()?

 2
Author: Toktik, 2011-10-29

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');
}
 5
Author: kiamlaluno, 2013-01-16 19:06:22