У меня есть много разных отношений для заказов и продуктов.
<?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'); }