cakePHP-как получить количество элементов для связанной модели?

модели: stores и product, и они связаны с:

var $belongsTo = array(
  'Store' => array(
    'className' => 'Store',
    'foreignKey' => 'store_id'
        ))

var $hasMany = array(
  'Product' => array(
'className' => 'Product',
'foreignKey' => 'store_id'
    ))

Я хочу получить список всех магазинов и количество продуктов, которые они имеют. Как изменить вызов:$this->Store->find('all', array(<..some conditions..>)) чтобы вернуть этот тип данных?

5 ответов


один из методов заключается в использовании встроенного торта counterCache в вашей ассоциации. Это, вероятно, самый эффективный вариант, хотя он требует добавления поля в таблицу.

в своем stores стол, добавьте


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

$this->Store->virtualFields = array('product_count' => 'COUNT(Product.id)');
$this->Store->find('all', array(
    'fields' => array('Store.id', 'Store.product_count'),
    'group' => array('Store.id'),
));

после CakePHP 2.0 вы также можете добавить условия на ваш счет и несколько счетчиков на модель.

добавьте любое целое поле в свой Store тогда используйте это в своем Product модель:

var $belongsTo = array(
    'Store' => array(
        'className' => 'Store',
        'foreignKey' => 'store_id',
        'counterCache' => array(
            'anyfield', array('Product.id >' => 0),
            'stock' => array('Product.status' => 'stock')
        )
    )
);

проверить find('count').

однако, это может не масштабироваться хорошо, если вы ищете пара эти данные с данными магазина (см. ответ therealtomrose).

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


простой найти все будет получать необходимые данные:

$Stores = $this->Store->find('all');

количество продуктов в одном из магазинов может быть возвращено со следующим кодом, где " 0 " может быть заменено номером индекса массива магазина:

count($Stores[0]['Products']); //returns an integer

Если вы хотите подсчет продуктов в каждом магазине, вы можете рассмотреть возможность зацикливания на всех магазинах таким образом:

foreach ($Stores as $Store) {
    echo count($Store['Products']);
}

предположения, которые я делаю:

  1. вы хотите подсчет продуктов в каждом магазине, а не общее количество продуктов.
  2. вы не слишком озабочены производительностью. Если у вас более 50 000 записей или около того, вы можете рассмотреть возможность сопряжения этого обратно, но это будет значительно сложнее.