У меня есть приложение 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
до нужной суммы.
Надеюсь, эта дополнительная информация поможет кому-то.