1 to n relationship in laravel 5.6 - php

i have an invoice model that i want it to have 'n' products in it so in my invoice model i place a relation hasMany like below
public function products(){
return $this->hasMany('App\Product','id','product_id');
}
so in database of invoice i create 5 fields for products and a quantitiy for each of products
$table->increments('id');
$table->text('title');
$table->longText('description');
$table->integer('client_id');
$table->integer('product_id1');
$table->integer('product_quantity1');
$table->integer('product_id2')->nullable();
$table->integer('product_quantity2')->nullable();
$table->integer('product_id3')->nullable();
$table->integer('product_quantity3')->nullable();
$table->integer('product_id4')->nullable();
$table->integer('product_quantity4')->nullable();
$table->integer('product_id5')->nullable();
$table->integer('product_quantity5')->nullable();
i want to know is it the right way to do this or i should make a table contain the id of product and the id of invoice to combine them with each other ??? and if i have to make a new table how should i set the relations ?
thanks

This looks similar to Many To Many approach between invoice and products. Add a junction table (invoice_products) which connects invoice and products, table should have invoice_id, product_id , Also have pivot attribute for quantity for each product like
For many to many you can add definitions in your models like
class Invoice extends Model
{
public function products()
{
return $this->belongsToMany(Product::class, 'invoice_products', 'invoice_id')
->withPivot('quantity')
->as('invoice_products_pivot');
}
}
class Product extends Model
{
public function invoices()
{
return $this->belongsToMany(Invoice::class, 'invoice_products', 'product_id');
}
}

Related

Sum Pivot Table's Column Laravel

I have 5 tables: sales_orders, product_sales_order (pivot table between sales_orders and products), products, shipment, and product_shipment (pivot table between shipment and products).
SalesOrder.php
class SalesOrder extends Model
{
public function products()
{
return $this->belongsToMany(Product::class)
->using(ProductSalesOrder::class)
->withPivot(['qty', 'price']);
}
public function shipments()
{
return $this->hasOne(Shipment::class);
}
}
ProductSalesOrder.php
class ProductSalesOrder extends Pivot
{
public function getSubTotalAttribute()
{
return $this->qty* $this->price;
}
}
Shipment.php
class Shipment extends Model
{
public function salesOrder()
{
return $this->belongsTo(SalesOrder::class);
}
public function products()
{
return $this->belongsToMany(Product::class)
->withPivot(['qty']);
}
}
Here what I want to achieve
Since 1 sales_order able to ship the product several times, I need to know how many products that already shipped before. And when I create new shipment, I need to limit the maximum qty that can be send at that time.
In this case, sales_order has 2 products with order qty 100 pcs each. Yesterday, I create 2 shipment which is 25 pcs and 50 pcs for product A. When I want to create new shipment for today, I can only send 25 pcs for product A and 100 pcs for product B.
I've tried my own way, using nested foreach and store the value that I want to an array. But is it possible to sum the qty inside product_shipment and compare it with the qty that has been ordered using eloquent?

fetch join table data using eloquent laravel

I am new to laravel & want to implement eloquent relationship.
Let me explain.
Consider I have 2 tables
products
product_id
product_name
brand_id
price
brands
id
brand_name
Each product will have one brand Id.But in Brands table, there is no product id. One brand_id can be in multiple product rows, and one product has one brand_id only. I want to select some col from products table plus brand_name with respect to brand_id of products table using Model.SO in Product model I wrote:
public function brands()
{
return $this->hasOne('App\Brand','product_id');
}
and in Brand model I write:
public function products()
{
return $this->belongsTo('App\Product','brand_id');
}
Now I want the result:
product_name
price
brand_name
How can I fetch those data in controller using eloquent relation? Also, the way I wrote Model relationship, Is it ok??
Your Product Model relation will be below
public function brand(){
return $this->belongsTo('App\Brand','brand_id');
}
public function product(){
return $this->belongsTo('App\Product','product_id');
}
Now in controller you can add query as below.
$products = Product::with('brand','product')->get();
echo '<pre>'
print_r($products->toArray());
exit;
It looks to me like you want a one-to-many relationship, so one brand can have many products and many products belong to one brand.
Product model:
public function brand()
{
return $this->belongsTo('App\Brand');
}
Brand model:
public function products()
{
return $this->hasMany('App\Product');
}
Then you would be able to get the brand information like this:
The full brand model:
Product::first()->brand
The brand name:
Product::first()->brand->brand_name
From the docs:
A one-to-many relationship is used to define relationships where a
single model owns any amount of other models. For example, a blog post
may have an infinite number of comments.
P.S.:
Your table column names do not make much sense to me, why do you have product_id on products but then on brands it is just called id? Why do you have product_name but then just price? why is it not just name or product_price, so your at least consistent?

Fire event on pivot table laravel

There are two Product and Warehouse models that have many to many relation ship with an extra stock field that specify stock of a product in a warehouse.
Product Model :
public function warehouses()
{
return
$this->belongsToMany(Warehouse::class, 'product_warehouse', 'product_id', 'warehouse_id')
->withPivot('stock')
->withTimestamps();
}
And Warehouse Model :
public function products()
{
return $this->belongsToMany(Product::class, 'product_warehouse', 'warehouse_id', 'product_id')->withPivot('stock')->withTimestamps();
}
User can do some operations like stock correction or transfer products from one warehouse to another one. and in each of them I increase or decrease stock column of row that relates that product and warehouse.
Now I want to delete whole row of pivot table if stock is equal 0.
How Can I do that ?

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');
}
}

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.

Categories