Получение подсчета из сводной таблицы в laravel eloquent

У меня есть много разных отношений для заказов и продуктов.

<?php class Order extends Eloquent { public function user() { return $this->belongsTo('User'); } public function products() { return $this->belongsToMany('Product'); } } ?> <?php class Product extends Eloquent { public function orders() { return $this->belongsToMany('Order'); } } ?> 

Необходимо получить количество заказов, каждое из которых заказывается. В mysql эту задачу можно выполнить, используя следующий запрос

 SELECT products.id, products.description, count( products.id ) FROM products INNER JOIN order_product ON products.id = order_product.product_id INNER JOIN orders ON orders.id = order_product.order_id GROUP BY product_id LIMIT 0 , 30 

Результат вышеуказанного запроса выглядит следующим образом:

 id description count(products.id) 1 Shoes 3 2 Bag 2 3 Sun glasses 2 4 Shirt 2 

Как эта задача может быть достигнута с помощью laravel eloquent (без использования построителя запросов)? Как я могу получить количество раз, когда каждый продукт заказывается с использованием laravel eloquent ??

Имейте в виду, что Eloquent использует Query\Builder под капотом, поэтому в Laravel нет такой вещи, как «запрос красноречивый без использования построителя запросов».

И это то, что вам нужно:

 // additional helper relation for the count public function ordersCount() { return $this->belongsToMany('Order') ->selectRaw('count(orders.id) as aggregate') ->groupBy('pivot_product_id'); } // accessor for easier fetching the count public function getOrdersCountAttribute() { if ( ! array_key_exists('ordersCount', $this->relations)) $this->load('ordersCount'); $related = $this->getRelation('ordersCount')->first(); return ($related) ? $related->aggregate : 0; } 

Это позволит вам воспользоваться энергичной загрузкой:

 $products = Product::with('ordersCount')->get(); // then for each product you can call it like this $products->first()->ordersCount; // thanks to the accessor 

Узнайте больше о Eloquent accessors & mutators ,

и о динамических свойствах , поведение которых приведено выше.


Конечно, вы можете использовать простые объединения, чтобы получить точно такой же запрос, как в вашем примере.

Для будущих зрителей, как и в Laravel 5.2, есть встроенная функция для подсчета отношений без их загрузки без привлечения вашей модели ресурсов или аксессуаров –

В контексте примера в одобренном ответе вы должны указать в своем контроллере:

 $products = Product::withCount('orders')->get(); 

Теперь, когда вы выполняете итерацию через $ продукты на вашем представлении, в каждой полученной записи продукта есть orders_count (или, как orders_count , только {resource}_count ), который вы можете просто отображать, как и любое другое значение столбца:

 @foreach($products as $product) {{ $product->orders_count }} @endforeach 

Этот метод производит 2 запросов к базе данных по сравнению с утвержденным методом для одного и того же результата, и единственное вовлечение модели – это правильно настроить ваши отношения. Если вы используете L5.2 + в этот момент, я бы использовал это решение.

Если у вас уже есть объект $ products, вы можете сделать следующее:

 $rolecount = $products->roles()->count(); 

Или если вы используете нетерпеливую загрузку:

 $rolecount = $products->roles->count(); 

Приветствия.

Я использую Laravel 5.1, и я могу это сделать, делая это

  $photo->posts->count() 

И метод posts в Photo model выглядит так

 public function posts(){ return $this->belongsToMany('App\Models\Posts\Post', 'post_photos'); }