У меня есть много ко многим отношениям для заказов и продуктов.
<?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
Узнайте больше о Красноречивые средства доступа & мутаторов,
и о динамические свойства, поведение которого вышеупомянутый аксессор имитирует.
Конечно, вы можете использовать простые объединения, чтобы получить точно такой же запрос, как в вашем примере.
Для будущих зрителей, начиная с Laravel 5.2, есть встроенная функциональность для подсчета отношений без их загрузки, без привлечения вашей модели ресурсов или средств доступа —
В контексте примера в утвержденном ответе вы поместите в свой контроллер:
$products = Product::withCount('orders')->get();
Теперь, когда вы просматриваете $ products в вашем представлении, возникает 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()
И метод сообщений в модели Photo выглядит следующим образом
public function posts(){
return $this->belongsToMany('App\Models\Posts\Post', 'post_photos');
}