Пагинация в CakePHP с виртуальными полями не возвращает пустой массив, когда нет результатов - PullRequest
2 голосов
/ 12 октября 2011

Я использую виртуальное поле в модели. Это поле представляет сумму нескольких полей: SUM(Model.amount_1 + Model.amount_2 + ...). Это схема:

create table `current_transfers` (
  `id` integer unsigned not null auto_increment primary key,
  `description` varchar(1024) not null,
  `product_amount` decimal(13,2) default 0.0 not null,
  `tax_amount` decimal(13,2) default 0.0 not null,
  `other_amount` decimal(13,2) default 0.0 not null,
  `record_id` integer unsigned not null,
  constraint foreign key (`record_id`) references `records`(`id`) on delete cascade,
) ENGINE=InnoDB;

И это определение виртуального поля в CurrentTransfer модели:

var $virtualFields = array(
  'amount' => 'SUM(
    CurrentTransfer.product_amount +
    CurrentTransfer.tax_amount +
    CurrentTransfer.other_amount)'
);

Допустим, в таблице еще нет записей, и вы используете $this->paginate() в RecordsController для получения списка результатов, например:

class RecordsController extends AppController {

  var $name = 'Records';

  var $paginate = array(
    'CurrentTransfer' => array(
      'order' => array('CurrentTransfer.amount' => 'desc'),
    ),
  );

  // ...

  public function view($id) {
    // ...
    $this->paginate('CurrentTransfer', array('CurrentTransfer.record_id' => $id));
    // ...
  }

  // ...
}

Я обнаружил два разных поведения:

  • Если виртуальное поле фактически определено в модели, результатом является массив с одним элементом, хранящим пустую запись, т. Е. Каждое поле имеет значение NULL.
  • Если виртуальное поле не определено в модели, результатом является пустой массив, который является обычным поведением в CakePHP, когда запрос возвращает пустой набор значений.

Я бы всегда ожидал второго поведения, поскольку его легче сравнивать, если есть результаты или нет.

Почему CakePHP возвращает фиктивный результат, когда в таблице фактически нет записей? Почему сложение виртуальных полей приводит к такому поведению?

1 Ответ

1 голос
/ 13 октября 2011

SUM() - агрегатная функция, которая суммирует все строки в столбце, а не все столбцы в строке, как вы, вероятно, хотите.Как агрегатная функция, она всегда возвращает значение, по крайней мере, NULL.Это означает, что запрос SQL возвращает хотя бы одну строку со всеми столбцами, установленными на NULL.Cake просто подхватывает это.

Я думаю, что вы действительно ищете это:

public $virtualFields = array(
  'amount' => 'CurrentTransfer.product_amount + CurrentTransfer.tax_amount + CurrentTransfer.other_amount'
);

Т.е. простой оператор + без SUM().

...