laravel "->ofMany()" for many-to-many pivot (belongsToMany) relationship - laravel

For a user with many orders (hasMany relationship), I can use hasOne with ofMany(), e.g.
public function orders()
{
return $this->hasMany(Order::class);
}
public function largestOrder()
{
return $this->hasOne(Order::class)->ofMany('price', 'max');
}
How can I achieve the same for a many to many relationship?
E.g. a product can have many categories (and each category has a weight),
and I want to get the products and their preferred category (=max weight).
// Product
public function categories() {
return $this->belongsToMany(Category::class);
}
// Category
public function products() {
return $this->belongsToMany(Product::class);
}
The following does not work:
// Product
public function preferredCategory() {
return $this->hasOne(Category::class)->ofMany('weight','max');
}
// Product::where('id',1)->with('preferredCategory')
// Column not found: 1054 Unknown column 'categories.product_id'
Suggestions? Using Laravel 9.

Related

Laravel Relationship : retrieve product that belongs to user cart from transaction

I have error like this :
Column not found: 1054 Unknown column 'products.user_id' in 'on clause' (SQL: select products.*, carts.product_id as laravel_through_key from products inner join carts on
How do i retrieve/access product that belongs to user cart from transaction table?
so this is my class diagram pict
this is my Transactions table :
public function user()
{
return $this->belongsTo(User::class, 'user_id','id');
}
public function transactionDetails()
{
return $this->hasMany(TransactionDetails::class);
}
My User table :
public function transaction()
{
return $this->hasMany(Transaction::class, 'user_id');
}
public function carts()
{
return $this->hasManyThrough(Product::class,Cart::class,
'product_id','user_id','id','id');
}
For Cart table, i got this :
public function products()
{
return $this->belongsTo(Product::class);
}
public function users()
{
return $this->belongsTo(User::class);
}
And to show user current transaction, i use this
$transactionByUser = Transaction::with('user.carts.products')->where('user_id',Auth::user()->id)->get();
In your case
class User extends Authenticatable
{
public function cart_items() {
return $this->belongsToMany(Product::class, 'carts');
}
}
class Product extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'carts');
}
}
And you can sync/attach products to user with:
// Products IDS
$product_ids= [1, 2];
// Then use
$user->cart_items()->attach($product_ids); // adds to existing
// OR
$user->cart_items()->sync($product_ids); // only this will be in your cart
To get the cart items
foreach($user->cart_items as $cart_item) {
// do stuff
}
For logged user you can use
foreach(auth()->user()->cart_items as $cart_item) {
// do stuff
}

Laravel get all products from parent category or subcategory using eloquent

I would like to retrieve all products of chosen parent category.Product model have hasmany relation to product_category_mapping table.
If product have subcategory result like,
"MAinCatergory":[
{
id="",
name:"Drinks",
"ChildCategory":[
{
"id":1,
"name":"Juce",
"Products":[{
name:"apple juce",
price:10,
....
}]
}
]
}
]
}
If product under main category only return array like,
"MAinCatergory":[
{
id="",
name:"Drinks",
"Products":[{
name:"apple juce",
price:10,
....
}]
}
}
]
}
category table fields - id,name,parent_id
product table fields - id,name,price,..,
product-category-mapping table fields - id,category_id,product_id
category model
public function children()
{
return $this->hasMany('App\Models\Category', 'parent_id');
}
public function parent()
{
return $this->belongsTo('App\Models\Category', 'parent_id');
}
public function product_category()
{
return $this->hasMany('App\Models\ProductCategoryMapping', 'category_id');
}
product model
public function product_category()
{
return $this->hasMany('App\Models\ProductCategoryMapping','product_id');
}
product-category_mapping
public function product()
{
return $this->belongsTo(Product::class,'product_id','id');
}
public function category()
{
return $this->belongsTo(Category::class,'category_id','id');
}
Something like this might suffice.
App\Models\Category::with('children', 'product_category.product')->get()
Suggestion, try implement pivot many to many relation instead this product_category_mapping, then model relation would change a bit.
For pivot relation, you need to modify the Category model
public function products()
{
return $this->belongsToMany('App\Models\Product', 'product-category-mapping');
}
and in product Model
public function categories()
{
return $this->belongsToMany('App\Models\Category','product-category-mapping');
}
Note:This is not the complete integration, but to give you an idea, for full logic see https://laravel.com/docs/9.x/eloquent-relationships#many-to-many
in your product model add like this:
public function product_categorys(){
return $this->hasMany('App\Models\ProductCategoryMapping','product_id');
}
and in controller you can get inside your function like this Product::with('product_categorys')->get();

Reach the subcategory from the Product model (Laravel)

I am trying to reach the last laravel model from the first one with eloquent relationships. How can I reach the Subcategory directly from Product?
The 3 Models I have:
Product (id, category_id, etc..)
public function categories()
{
return $this->belongsTo('App\Category', 'category_id');
}
Category (id, name)
public function products()
{
return $this->hasMany('App\Product', 'category_id');
}
public function sub_categories()
{
return $this->hasMany('App\SubCategory', 'category_id');
}
SubCategory (id, category_id, name)
public function categories()
{
return $this->belongsTo('App\Category', 'category_id');
}
I would've assumed I could reach it with
Product::find(1)->categories->sub_categories;
Am I missing something obvious here?
read this docs
Product
class Product extends Model
{
public function SubCategory()
{
return $this->hasManyThrough('App\Category', 'App\SubCategory');
}
}
In Addition add the subCategories method on Product model and also a product is belongs to a category not categories
and also always try to use camel case for the methods (subCategories)
replace your code with this
Product:
public function category()
{
return $this->belongsTo('App\Category', 'category_id');
}
public function subCategories()
{
return $this->category()->subCategories;
}
Category:
public function products()
{
return $this->hasMany('App\Product', 'category_id');
}
public function subCategories()
{
return $this->hasMany('App\SubCategory', 'category_id');
}
SubCategory:
public function categories()
{
return $this->belongsTo('App\Category', 'category_id');
}
finally use this to get the subcategories
Product::find(1)->subCategories;
Product::find(1)->categories is an array. You will have to loop it to get the subcategory of each category. See below
$categories = Product::find(1)->categories;
foreach ($categories as $category {
//Get subcategories for each category
dump($category->sub_categories);
}

Laravel BelongsToMany with two pivot table

I have the following table structure:
products
id
product_formats
id
product_id
product_prices
id
product_format_id
market_id
markets
id
A product can have multiple formats, with each having their own price which belongs in a different market. How can I retrieve the list of Markets from the Product model?
I used to have a single pivot table, however now I have two pivot.
class Product extends Model
{
public function markets()
{
return $this->belongsToMany(Market::class);
}
}
Update
To get the result I want, I did the following:
public function markets()
{
return Market::whereIn('id', $this->prices()->distinct()->pluck('market_id')->toArray());
}
However, I'm wondering if there's a way to accomplish this via a relationship.
You need to build relationships in models.
ProductModel:
public function productFormats()
{
return $this->belongTo(ProductFormatsModel::class);
}
ProductFormatsModel:
public function productPrices()
{
return $this->belongTo(ProductPricesModel::class);
}
ProductPricesModel:
public function markets()
{
return $this->hasOne(MarketsModel::class);
}
in Controller:
foreach($product->productFormats as $productFormat)
{
foreach($productFormat->productPrices as $productPrice)
{
var_dump($productPrice->markets);
}
}
For unique markets
in ProductModel:
public function productPrices()
{
return $this->hasManyThrough(
'App\ProductPricesModel',
'App\ProductFormatsModel',
'product_id',
'product_format_id'
'id',
'id'
);
}
in Controller
foreach($product->productPrices as $productPrice)
{
var_dump($productPrice->markets)
}

Laravel many to many need column from join table

My two tables have relation in this way
public function orders() {
return $this->belongsToMany('App\Order');
}
public function products() {
return $this->belongsToMany('App\Product', 'OrderDetails');
}
How can i get column for quantity? Is defined on order_product table
Use withPivot():
public function orders() {
return $this->belongsToMany('App\Order')->withPivot('quantity');
}
$orders = Product::find($id)->orders;
foreach($orders as $order) {
// $order->pivot->quantity
}

Resources