cakePHP - как узнать количество предметов для связанной модели? - PullRequest
7 голосов
/ 18 ноября 2011

Модели: 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 ]

17 голосов
/ 18 ноября 2011

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

В вашей таблице stores добавьте поле INT с именем product_count

.Product модель добавляет опцию counterCache к вашей ассоциации:

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

Когда вы добавляете или удаляете записи Product, она автоматически обновляет поле product_count связанной записи Store,так что нет необходимости изменять ваши операции find.

Обратите внимание, что если вы выберете этот маршрут, вам нужно будет вручную обновить поле product_count, чтобы начальное значение было правильным, поскольку оно толькообновляет после операций добавления / удаления.

3 голосов
/ 18 ноября 2011

Я считаю, что что-то вроде следующего будет работать, однако я не могу проверить это отсюда. Содержимое 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'),
));
2 голосов
/ 02 июня 2013

После 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')
        )
    )
);
2 голосов
/ 18 ноября 2011

Выезд find('count').

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

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

1 голос
/ 18 ноября 2011

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

$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 записей или около того, возможно, вы захотите объединить их обратно, но это будет значительно сложнее.
...