Получение отсчета из сводной таблицы в 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 ??

5

Решение

Имейте в виду, что 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

Узнайте больше о Красноречивые средства доступа & мутаторов,

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


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

20

Другие решения

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

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

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

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

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

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

14

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

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

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

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

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

3

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

 $photo->posts->count()

И метод сообщений в модели Photo выглядит следующим образом

public function posts(){
return $this->belongsToMany('App\Models\Posts\Post', 'post_photos');
}
0
По вопросам рекламы [email protected]