I have 3 tables (products, product details, loan reports).
I want to display product categories in the loan report table. the product table has one-to-many relation with the product detail table and the product detail table has one-to-many relation with the loan report table.
Products
id
product_categories
Product Details
id
product_name
Loan Reports
id
date
amount
I've displayed it using this code,
$data = DB::table('loan_reports')
->join('product_details', 'loan_reports.product_details_id', '=', 'product_details.id')
->join('products', 'product_details.products_id', '=', 'products.id')
->get();
I want to do it with Eloquent orm but it's always get an error.
Help me please!
the column I want to display is roughly like this
| date | product_categories | product_name | amount |
The error that I get is the following:
Trying to get property 'product_name' of non-object
You might want to check out "has many through" relationship:
https://laravel.com/docs/5.8/eloquent-relationships#has-many-through
In ProductDetails model,create relationships.
public function product_info()
{
return $this->belongsTo('App\Models\Product','id','products_id');
}
public function loan_reports()
{
return $this->hasOne('App\Models\LoanReports','product_details_id','id');
}
Retrieve result using
$product_details = ProductDetails::get();
foreach($product_details as $product_details)
{
echo $product_details->product_categories;
if(isset($product_details->product_info))
{
echo $product_details->product_info->product_name;
}
if(isset($product_details->loan_reports))
{
echo $product_details->loan_reports->date;
echo $product_details->loan_reports->amount;
}
}
Related
I have favourites table like this:
id -user_id - product_id
It's for user to add the favourites product, and I have my relation in User Model:
public function favourites()
{
return $this->belongsToMany(Product::class ,'favourites')->withTimestamps();
}
How can I fetch the most product added to favorites by users! ?
You can use count(*) with group by.
Favorite::selectRaw('product_id, count(product_id) as times_added')
->groupBy('product_id')
->orderByDesc('times_added')
// ->limit(5) if you want to get the top 5
->get();
If you don't have a model for your favorites table you can use the DB facade.
DB::table('favorites')
->selectRaw('product_id, count(product_id) as times_added')
->groupBy('product_id')
->orderByDesc('times_added')
// ->limit(5) if you want to get the top 5
->get();
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?
I have a mini problem in my application... I want to get all products from the products table along with the category name from the categories table and get stock of each product from products_attribute table... the problem is product table id overwrite with products_attribute id. In the product_attributes table, only 116 rows but products table has 177 rows and the loop gets only 116 rows with products_attribute id.
Product Table (Screenshot)
Product Attributes Table (Screenshot)
Categories Table (Screenshot)
public function viewProducts(Request $request)
{
$products = Product::join('categories', 'categories.id', 'products.category_id')->join('products_attributes', 'products_attributes.product_id', 'products.id')->get();
$products = json_decode(json_encode($products));
return view('admin.products.view_products')->with(compact('products'));
}
Laravels join function default is inner join so You will need to use the leftJoin method. (See \vendor\laravel\framework\src\Illuminate\Database\Query\Builder#join)
I hope It will be helpful.. How to use left join:
$products = Product::join('categories', 'categories.id', 'products.category_id')->leftjoin('products_attributes', 'products_attributes.product_id', 'products.id')->get();
You have to use aliases to preserve columns from the base table that will be overwritten by your joining table(s):
$products = Product::select('*', \DB::raw("product.id as product_id"))->join('categories', 'categories.id', '=', 'product.id')->get();
You can then access the product id using: $product->product_id
I have 3 tables: reports, fields and report_fields which is a pivot between the other 2. What i need to do is order report_field.field by the position column in the field table.
I tried ordering in the relation in the Models or when using with but I may be doing it wrong.
ex:
$query = Report::with([ 'reportFields.field' => function ($q) {
$q->orderBy('position', 'asc');
//$q->orderByRaw("fields.position DESC");
},
Can someone give a basic example of ordering a 2 level nested relationship?
Edit: I do not need to order by any column in the base table but the list of entries in the pivot table by an column in the second table.
Edit2:
To give an example how the output should be ordered:
Report
ReportField
Field.position = 1
ReportField
Field.position = 2
ReportField
Field.position = 3
You can add your needed ordering on the relation of the first table reports:
public function reportFields()
{
return $this->hasMany(ReportFields::class)
->select('report_fields.*')
->join('fields', 'report_fields.field_id', 'fields.id')
->orderBy('fields.position', 'asc');
}
I have a maintenance table with the following fields: id, car_id, type, and name.
How do I get list of entries from maintenance table where type = 'car wash' but only with model_id = 5?
model_id field are in the car table. Car table with the following fields: id, model_id, engine_size, and color.
How can I use Maintenance::where to get list of entries with matching model_id in a car table? There is car_id in a maintenance table which link with car table.
Do I need to do something like this: ?
return Maintenance::where('type', 'car_wash')->where(function($query) {
// get a list a maintenance where model_id = 5 in a car table
});
Assuming you've already defined cars() relation on your Maintenance model you could try something like that:
$model_id = 5;
$type = 'car_wash';
return Maintenance::whereHas('cars',function($query) use($model_id,$type) {
$query->where('model_id',$model_id)->where('type',$type);
})->get();
Update for further question (skip if $model_id = 0):
return Maintenance::whereHas('cars',function($query) use($model_id,$type) {
if($model_id!=0){
$query->where('model_id',$model_id);
}
$query->where('type',$type);
})->get();
I did not tested it but it should work, otherwise let me know