Модель CakePHP: COUNT (*) в контейнере

У меня есть приложение CakePHP 1.3 и действительно наслаждаюсь Containable поведением для получения данных.

Предположим, что у меня есть сообщения в отношениях «один ко многим» с комментариями. Я использую Containable для запроса (для разбивки на страницы) списка всех сообщений и принадлежащих комментариев. Но меня интересует только то, сколько комментариев у каждой Почты. Я не нашел никакого способа достичь этого запроса с помощью сдерживаемого без извлечения всех строк комментариев. Я пытался:

$this->paginate=array( 'fields' => 'Post.title, Post.created', 'contain' => array('Comment'=>'COUNT(*) AS count'), ); 

результаты «Модель» Комментарий «не связаны с сообщением об ошибке« Count ».

 $this->paginate=array( 'fields' => array('Post.title, Post.created'), 'contain' => array('Comment'=>array('fields'=>'COUNT(*) AS count'), ); 

не работает, набор результатов содержит для каждого столбца пустой массив комментариев, за исключением последнего, где он содержит поле count, но имеет количество всех комментариев не только принадлежащих им.

Мое другое предположение было

 $this->paginate=array( 'fields' => 'Post.title, Post.created, COUNT(Comment.id)', 'contain' => array('Comment'=>array('fields'=>''), ); 

но это приводит к ошибке, так как отношения hasMany запрашиваются независимо, поэтому таблица ответов не находится в запросе записей Post. Как я могу подсчитать количество комментариев в сообщении?

Ну, лучший способ сделать это – настроить поле comment_count в таблице posts и добавить этот ключ к модели Comment $ arrayTo Post:

'counterCache' => true

Каждый раз, когда что-либо будет происходить с комментариями, поле comment_count в соответствующем сообщении будет обновляться (на самом деле, он пересчитывается каждый раз, а не просто добавляет или удаляет).

Это лучше, потому что, когда вы извлекаете данные для пользователя, его способ быстрее и даже не касается таблицы комментариев. Поскольку вы используете Containable поведение, я думаю, что скорость и легкий вес – это то, что вы ищете.

У меня такой же вопрос. Ответ, который дал PawelMysior, был отличным и привел к решению.

Я нашел некоторые дополнительные сведения в книге CakePHP: 3.7.4.1.1 counterCache – кэширует ваш счетчик () . Это было полезно, но все еще немного расплывчато. Ради других, я хочу представить некоторые дополнительные подробности.

У меня есть две таблицы: «Почта» и «Изображение». Когда я добавлял изображение в сообщение, я хочу отслеживать, сколько изображений, которое каждое сообщение имело для отображения в списке индексов Post, без необходимости запуска дополнительного счетчика в таблице изображений.

 CREATE TABLE posts ( id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, user_id INTEGER UNSIGNED NOT NULL, title VARCHAR(255), body TEXT, created DATETIME, modified DATETIME, image_count INTEGER UNSIGNED, PRIMARY KEY (id) ) ENGINE=InnoDB; CREATE TABLE images ( id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, post_id INTEGER UNSIGNED NOT NULL, filename VARCHAR(255), created DATETIME, modified DATETIME, PRIMARY KEY (id) ) ENGINE=InnoDB; 

Обратите внимание, что image_count входит в таблицу posts . В таблице images ничего особенного не требуется.

 class Post extends AppModel { var $name = 'Memory'; var $hasMany = array( 'Image' => array( 'className' => 'Image', 'foreignKey' => 'post_id', 'dependent' => false ) ); } class Image extends AppModel { var $name = 'Image'; var $belongsTo = array( 'Post' => array( 'className' => 'Post', 'foreignKey' => 'post_id', 'counterCache' => true ) ); } 

Обратите внимание, что counterCache добавляется в модель Image . В модели Post ничего особенного не требуется.

 $this->Post->Behaviors->attach('Containable'); $post = $this->Post->find('all', array( 'conditions' => array('user_id' => 7), 'order' => array('Post.created DESC'), 'contain' => array( 'Post' => array( 'User' => array('first_name', 'last_name') ) ) )); 

Теперь, когда мы делаем find нет необходимости делать что-либо особенное, чтобы найти счет, потому что оно автоматически является полем в результатах Post . Обратите внимание на image_count ниже.

 Array ( [Post] => Array ( [0] => Array ( [id] => 14 [user_id] => 7 [title] => Another great post [body] => Lorem ipsum... [created] => 2011-10-26 11:45:05 [modified] => 2011-10-26 11:45:05 [image_count] => 21 [User] => Array ( [first_name] => John [last_name] => Doe ) ) ) ) 

Следует отметить, что если вы добавите counterCache в существующую структуру базы данных, счетчики в Post будут равны нулю до тех пор, пока не добавится другое Image . В данный момент CakePHP будет выполнять фактический подсчет и обновлять image_count до нужной суммы.

Надеюсь, эта дополнительная информация поможет кому-то.