Sum pivot table field on Eloquent many-to-many relationship - php

I have an orders table, an items table, and a pivot table called item_order which has two custom fields (price, quantity). The relationship between Order and Item is belongsToMany. I'm trying to return the count of all items with an id of 1, where the parent Order->status == 'received'. For the life of me, I can't figure out how to do this.
class Order extends Model
{
public function items()
{
return $this->belongsToMany(Item::class)->withPivot('price', 'quantity');
}
}
class Item extends Model
{
public function orders()
{
return $this->belongsToMany(Order::class)->withPivot('price', 'quantity');
}
}

Try this:
$total_quantity = Item::find(1) // getting the Item
->orders() // entering the relationship
->with('items') // eager loading related data
->where('status', '=', 'received') // constraining the relationship
->get() // getting the results: Collection of Order
->sum('pivot.quantity'); // sum the pivot field to return a single value.
The strategy here is to find the desired Item to then get the related Orders to this Item that has a 'received' status, to finally sum the pivot attribute in order to get a single value.
It should work.

Considering you know the id of the item, most performant way would be to query item_order table directly. I would create a pivot model for ItemOrder and define the belongsTo(Order::class) relationship and do this:
$sum = ItemOrder::where('item_id', $someItemId)
->whereHas('order', function ($q) {
return $q->where('status', 'received');
})
->sum('quantity');

Related

How to Join Eloquent and Query Builder in one query statement in laravel

I have 2 queries that needed to join 1st is eloquent and 2nd is query builder,
1st Query
$products = Product::all();
2nd Query
$inventory = DB::table('product_warehouse')
->where('product_id', $product_id)
->where('warehouse_id', $warehouse_id)
->first();
How to merge this 2 queries into elouquent way ?
From your usage of the query builder it seems like you have an intermediate table to store which product to which warehouse exist, but if it is a one to many relationship you should not have that table, instead in your products table you should have a warehouse_id which will reference the id on the warehouses table, as you said the relationship is one to many, not many to many.
So in your Warehouse model you can add:
public function products()
{
return $this->hasMany(Product::class);
}
And in your Product model:
public function warehouse()
{
return $this->belongsTo(Warehouse::class);
}
Based on your table name, you might need to set the $table in your warehouse model to match that:
protected $table = 'product_warehouse';
Then you have many ways to fetch it, one of which is :
Warehouse::find($warehouse_id)->products;
// or
Warehouse::with('products')->where('id', $warehouse_id)->get();
// to get the warehouse to which the product belongs to
Product::find($product_id)->warehouse;

Laravel Eloquent many to many relationship with different column as key

I have the following models
Category
id // we don't want to use this one for the relation
category_id // we want to use this
Product
id
CategoryProduct
product_id // points to "id" on products table
category_id // points to **category_id** on categories table
I have the Product model set up as follows (only the most recent variation).
class Product {
public function categories() {
return $this->belongsToMany('Category', 'categories_products', 'category_id');
}
}
When I try to get a product with categories as follows...
Product::with('categories')->get();
I either get the wrong categories because the query is using id on categories as the foreign key. I need it to be using category_id on the categories table.
Or I get none at all. I can't seem to hash out how to set up which columns to use on the belongsToMany method.
Try this follow,
class Product {
public function categories() {
return $this->belongsToMany('Category', 'categories_products', 'product_id','category_id');
}
}

how to use where for relationship in laravel eloquent?

I want to use where clause on the another relationship not my current selecting model as below table
table Customer
-------id-----customer_name
Table ModelA
table Customer
-------id-----fk_custome_id
table ModelB
-------id-----fk_ModelA_id
Function in Controller
$data['data'] = customer::with(['modelA','modelA.modelB'])
->where('fk_customer_id', 2)->get();
Customer Model
final function ModalA (){
return $this->hasMany('App\Models\ModelA', 'fk_customer_id', 'id');
}
ModelA Model
final function Modelb (){
return $this->hasMany('App\Models\ModelB', 'fk_modelA_id', 'id');
}
Error:
I will got error as below because select sql don't find the column name fk_customer_id in table customer, So how can I user fk_customer_id (in table ModelA) for where.
You can useYou can use whereHas like:
$data['data'] = customer::with(['modelA','modelA.modelB'])
->whereHas('modelA', function ($query) {
$query->where('fk_customer_id', 2);
})->get();
It's because when you're using with you just eager load constrints but you won't attach it to the main query (of the customer model). So there are two way: one modern with using whereHas or using join queries.

Eloquent many to many relationship access table column value from pivot table

I have two models:
class Order extends Eloquent
{
public function User()
{
return $this->belongsTo('User');
}
public function Product()
{
return $this->belongsToMany('Product');
}
}
and the second one is:
class Product extends Eloquent
{
public function Order()
{
return $this->belongsToMany('Order');
}
}
My question is how can i access a value of second table column using pivot table:
product table:
id
title
image
order table:
id
status
pivot table(order_product):
id
product_id
order_id
I need to access title column of products from orders. for example if a user orders many products in one order I can fetch all product title and show theme.
I don't like use join , instead I like to use Laravel functionality itself.
I found the answer:
$orders = Order::orderBy('created_at', 'DESC')->paginate($page_number);
foreach($orders as $item){
foreach($item->product as $item){
{{$item->title}}<br>
}
}
I can access products from order.

Laravel BelongsToMany Pivot Table : How to fetch selected columns

Want to get selected columns, when querying through pivot table. Following is my scenario.
I have 3 tables,
coupons
coupon_cities
cities
relationship details are as following.
class Coupon extends Eloquent {
public function cities(){
return $this->belongsToMany('City', 'coupon_cities', 'coupon_id', 'city_id');
}
}
When I query
Coupon::with('cities')
it returns array of all columns of city table for each entry of coupon row
The only way is this:
$coupon = Coupon->first();
$coupon->cities()->get([your columns here]);
Normally you'd do it like below:
Coupon::with(['cities' => function ($q)
{
$q->select('column', 'column2' ...);
}
However it won't work for belongsToMany relation -> https://github.com/laravel/framework/pull/4440

Categories