How to Foreach loop through Laravel collection.? - php

i m a beginner at laravel. using 5.5 . i have this collection return by my controller :
$products = Product::with('bazar.resellers')->take(2)->get();
dd($products);
//return view('shop.index')->with('products', $products);
which basically is three tables with nested relations. Note the relations lists in the code below. i want to access data(all columns in red colour) from every model i have in the collection i.e. Product, bazar and reseller.
Relationships are quite fine. but how to retrieve it from a collection? i dunno how foreach loops play with a collection.
Collection {#578 ▼
#items: array:2 [▼
0 => Product {#487 ▼
#fillable: array:7 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:10 [▼
"id" => 1
"created_at" => "2018-04-27 12:54:41"
"updated_at" => "2018-04-27 12:54:41"
"imgp" => "shirt.jpg"
"title" => "shirt1"
"Prod_descript" => "shirt1 is a good shirt"
"price" => 10
"reseller_id" => 1
"City_id" => 1
"bazar_id" => 1
]
#original: array:10 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"bazar" => Bazar {#523 ▼
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:7 [▼
"id" => 1
"Bazarname" => "Saddar"
"Bazarlat" => null
"Bazarlong" => null
"created_at" => null
"updated_at" => null
"City_id" => 1
]
#original: array:7 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"resellers" => Collection {#574 ▼
#items: array:1 [▼
0 => Reseller {#564 ▼
#guard: "reseller"
#fillable: array:12 [▶]
#hidden: array:2 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:15 [▼
"id" => 1
"Fname" => "talha"
"Lname" => "ali"
"email" => "p#g.com"
"password" => "$2y$10$M7wOmSouxSAYADN7NeFdSObT8fGwkEOFxVmOgcNSWvrixWCDtA/1S"
"mobile_no" => "03169880008"
"landline_no" => "0987654"
"shop_name" => "MyTestSHop"
"NIC_no" => "170178359437589754"
"shop_address" => "University Town, Peshawar, Pakistan"
"remember_token" => "wrb3nOwOWQcTuoF0P9KnaknwpOxfpTHt4gkShUmTzkR2Df9A7pPY5shBq6pQ"
"created_at" => "2018-04-27 12:42:25"
"updated_at" => "2018-04-27 12:42:25"
"City_id" => 1
"bazar_id" => 1
]
#original: array:15 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#visible: []
#guarded: array:1 [▶]
#rememberTokenName: "remember_token"
}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▼
0 => "*"
]
}
1 => Product {#488 ▶}
]
}
the code i have tried is not working!
#foreach($products as $product)
<h1>{{ $product->title }}</h1>
#foreach($product->bazar as $bazar)
<h3>{{ $bazar->Bazarname }}</h3>
#foreach($bazar->resellers as $reseller)
<p>{{ $reseller->Fname }}</p>
#endforeach
#endforeach
#endforeach

If product has single bazar,then you don't need to use foreach on $product->bazar. You just need to use bazar property directly. and if product has many bazars, then update your product model bazar() method like:
public function bazars()
{
return $this->hasMany(Bazar::class);
}
It returns collection of bazars and then you can run loop on that.

Related

Storing attributes of a multiple models, to single array in laravel

I have the following eloquent in my controller,
$getJobs=JobTitle::where('department_id',DepartmentUser::where('user_id', $user->id)->first()->department_id)->get();
This gives me following collection
Illuminate\Database\Eloquent\Collection {#2970 ▼
#items: array:3 [▼
0 => App\JobTitle {#2967 ▶}
1 => App\JobTitle {#2968 ▶}
2 => App\JobTitle {#2962 ▶}
]
#escapeWhenCastingToString: false
}
And one model element looks like this
1 => App\JobTitle {#2968 ▼
#connection: "mysql"
#table: "job_titles"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:9 [▼
"id" => 898
"title" => "driver"
"company_id" => 635
"department_id" => 252
"created_by" => null
"created_at" => "2022-04-20 05:30:38"
"updated_at" => "2022-04-20 05:30:38"
"deleted_at" => null
"archived_at" => null
]
#original: array:9 [▶]
#changes: []
#casts: array:2 [▶]
#classCastCache: []
#attributeCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: array:3 [▶]
#guarded: array:1 [▶]
+archives: true
#forceDeleting: false
}
Now I want to store all the job title (title) value's into single array
"title" => "driver"
In the above scenario, I have array elements and therefore I need store all three respective job titles to one single array...
$jobs = ['driver', 'chef', 'engineer'];
I tried adding an foreach, but it was giving me the following error,
#foreach ($getJobs as $getJob)
dd ($getJob->title);
#endforeach
ParseError syntax error, unexpected token "foreach"
What is the best way to achieve this?
You can simply loop on $getJobs and collect the title names in an array like below:
<?php
$getJobs = JobTitle::where('department_id',DepartmentUser::where('user_id', $user->id)->first()->department_id)->get();
$titles = [];
foreach($getJobs as $job){
$titles[] = $job->title;
}
dd($titles);

laravel collection group by then order by

maybe trivial but i'm stuck on this.
$questions = FaqQuestion::with('category')->get()->groupBy('faq_categories_id')->sortBy('sortorder');
The result is grouped by faq_categories_id, and sorted by FaqQuestion id it seems. I want to orderBy the 'sortorder' field ASC from FaqQuestion, the same column name exists in category.
Any input is appreciated. Thanks
edit:
$questions returns a collection:
Illuminate\Database\Eloquent\Collection {#1309 ▼
#items: array:3 [▼
1 => Illuminate\Database\Eloquent\Collection {#1154 ▼
#items: array:3 [▼
0 => App\FaqQuestion {#1385 ▼
+table: "faq_questions"
#dates: array:4 [▶]
#fillable: array:6 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:10 [▶]
#original: array:10 [▶]
#changes: []
#casts: []
#classCastCache: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
1 => App\FaqQuestion {#1387 ▶}
2 => App\FaqQuestion {#1388 ▶}
]
}
2 => Illuminate\Database\Eloquent\Collection {#430 ▶}
3 => Illuminate\Database\Eloquent\Collection {#431 ▶}
]
}

get one unique item from a laravel relationship

i have a 1 to n relation ship between product and images and on images i have a field called color_id which has a 1 to n with images . now what i want to do is to call the product with images relationship like below :
$relation = Product::with('images')->where('id',$product->id)->get();
dd($relation);
now what want is to get 1 images from each color_id so for example if this product has 3 images with color_id of 1 , and 4 images with color_id of 2 .i want to get 1 images from each color . and here is the dd result of $relation in case needed .
^ Illuminate\Database\Eloquent\Collection {#945 ▼
#items: array:1 [▼
0 => Webkul\Product\Models\Product {#912 ▼
#fillable: array:4 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:7 [▶]
#original: array:7 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"images" => Illuminate\Database\Eloquent\Collection {#968 ▼
#items: array:3 [▼
0 => Webkul\Product\Models\ProductImage {#967 ▼
+timestamps: false
#fillable: array:4 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▼
"id" => 17
"type" => null
"path" => "product/39/y0ueAFEgscD9ZsVFg7nT2WPNsU6vDyXWqLVONa8L.jpeg"
"product_id" => 39
"product_color_id" => 3
"product_size_id" => null
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => Webkul\Product\Models\ProductImage {#970 ▼
+timestamps: false
#fillable: array:4 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▼
"id" => 23
"type" => null
"path" => "product/39/M9JTVsy2BtNp8LuUQh7cp17S5jN1ifOZ1P9WZk3h.jpeg"
"product_id" => 39
"product_color_id" => 2
"product_size_id" => null
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
2 => Webkul\Product\Models\ProductImage {#969 ▼
+timestamps: false
#fillable: array:4 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▼
"id" => 24
"type" => null
"path" => "product/39/STA9sGKjWHWDn0wkmnVRqZYdI2adLE5qaIn7vyFQ.jpeg"
"product_id" => 39
"product_color_id" => 1
"product_size_id" => null
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
Try this
$relation =Product::with(array('images' => function($query) {
$query->groupBy('product_color_id');
})->where('id',$product->id)->get();

Getting list of discounted products in laravel

I try to get all of my discounted products in one page, but it doesn't return results
while the exact same query return results in homepage.
function
public function promotions() {
$promotions = Discount::with('products')->orderby('id', 'desc')->paginate(12);
return view('front.promotions', compact('promotions'));
}
route
Route::get('/promotions', 'frontend\FrontendController#promotions')->name('promotions');
blade
#foreach($promotions as $product)
{{$product->title}} // return nothing!
#endforeach
here is dd of my $product
dd code
Discount {#686 ▼
#table: "discounts"
#dates: array:2 [▶]
#fillable: array:4 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:8 [▶]
#original: array:8 [▼
"id" => 4
"value_from" => "2018-02-18"
"value_to" => "2018-02-19"
"amount" => "10000"
"product_id" => 16
"stock" => 25
"created_at" => "2018-02-19 09:05:48"
"updated_at" => "2018-02-19 09:47:10"
]
#changes: []
#casts: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"products" => Product {#697 ▼
#fillable: array:16 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:23 [▶]
#original: array:23 [▼
"id" => 16
"title" => "new product"
"slug" => "new-product"
"imageOne" => "productone-1519001703.png"
"imageTwo" => "producttwo-1519001703.jpg"
"short_description" => """
<!DOCTYPE html>\r\n
<html>\r\n
<head>\r\n
</head>\r\n
<body>\r\n
<p>eagtheyh</p>\r\n
</body>\r\n
</html>
"""
"description" => """
<!DOCTYPE html>\r\n
<html>\r\n
<head>\r\n
</head>\r\n
<body>\r\n
<p>shw4 bw 6r uwrurjw ryt jyhkiuggk</p>\r\n
</body>\r\n
</html>
"""
"price" => "100000"
"meta_description" => "gjyrj"
"meta_tags" => "yrujr,ujrtsdjr,jrjurysj,"
"arrivalDays" => "1"
"height" => "546"
"weight" => "56"
"lenght" => "56"
"width" => "56"
"sku" => "47ghg"
"stock" => "24"
"status_id" => 1
"brand_id" => 1
"category_id" => 1
"subcategory_id" => 1
"created_at" => "2018-02-19 07:55:03"
"updated_at" => "2018-02-21 09:58:04"
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#slugOptions: null
#configSettings: array:4 [▶]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
You need to iterate over discounts and products:
#foreach($promotions as $discount)
{{ $discount->products->title }}
#endforeach

Using select on eloquent model causes "Undefined offset:0"

I am new to laravel. I have written code like below. And when I add select, it causes an error saying undefined offset: 0.
It also causes same error when I have more than two records even though I commented out select part.
When I check the query using toSql(), it is perfectly fine.
So when I use dd() on $clientDrivers before return, the output is below. (Seems fine as well)
What would be the problem with my code?
Any suggestion or advice would be appreicated.
EDIT: I have found the problem which was the $appends in Driver Model. Why does $appends cause the problem?
Solution: I have fixed my Driver Model getBankAttribute which is used for $appends and it works fine.
Here is my code:
Model
public function drivers() {
return $this->belongsToMany('App\Model\User\Driver', 'ClientDriver', 'client_id', 'userdriver_id');
}
Controller
$client = ClientModel::findOrFail($id);
$select = ['UserDriver.name as userdriver_name', 'UserDriver.phone_number as userdriver_phone_number'];
$clientDrivers = $client->drivers()
->select($select) // this does not work. If this is commented out it works perfectly fine.
->get();
return response($clientDrivers, 200);
Result of dd($clientDrivers)
Collection {#805
#items: array:2 [
0 => Driver {#798
#dates: array:1 [
0 => "deleted_time"
]
#table: "UserDriver"
+timestamps: false
+appends: array:1 [
0 => "bank"
]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:2 [
"userdriver_name" => "driver1"
"userdriver_phone_number" => "140412351235"
]
#original: array:4 [
"userdriver_name" => "driver1"
"userdriver_phone_number" => "140412351235"
"pivot_client_id" => 1
"pivot_userdriver_id" => 1
]
#changes: []
#casts: []
#dateFormat: null
#dispatchesEvents: []
#observables: []
#relations: array:1 [
"pivot" => Pivot {#801
+pivotParent: Client {#713
#table: "Client"
#guarded: array:2 [
0 => "id"
1 => "created_time"
]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:20 [
"id" => 1
"created_time" => "2017-12-28 05:23:50"
"invoice_email" => ""
"biz_number" => "1234512345"
]
#original: array:20 [
"id" => 1
"created_time" => "2017-12-28 05:23:50"
"invoice_email" => ""
"biz_number" => "1234512345"
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#forceDeleting: false
}
#foreignKey: "client_id"
#relatedKey: "userdriver_id"
#guarded: []
#connection: "mysql"
#table: "ClientDriver"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:2 [
"client_id" => 1
"userdriver_id" => 1
]
#original: array:2 [
"client_id" => 1
"userdriver_id" => 1
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: false
#hidden: []
#visible: []
#fillable: []
}
]
#touches: []
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [
0 => "*"
]
#rememberTokenName: "remember_token"
}
1 => Driver {#799
#dates: array:1 [
0 => "deleted_time"
]
#table: "UserDriver"
+timestamps: false
+appends: array:1 [
0 => "bank"
]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:2 [
"userdriver_name" => "driver2"
"userdriver_phone_number" => "140412351236"
]
#original: array:4 [
"userdriver_name" => "driver2"
"userdriver_phone_number" => "140412351236"
"pivot_client_id" => 1
"pivot_userdriver_id" => 2
]
#changes: []
#casts: []
#dateFormat: null
#dispatchesEvents: []
#observables: []
#relations: array:1 [
"pivot" => Pivot {#803
+pivotParent: Client {#713}
#foreignKey: "client_id"
#relatedKey: "userdriver_id"
#guarded: []
#connection: "mysql"
#table: "ClientDriver"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:2 [
"client_id" => 1
"userdriver_id" => 2
]
#original: array:2 [
"client_id" => 1
"userdriver_id" => 2
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: false
#hidden: []
#visible: []
#fillable: []
}
]
#touches: []
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [
0 => "*"
]
#rememberTokenName: "remember_token"
}
]
}
You need to pass string in $select. You are currently passing array in it.
Change your $select as below:
$select = "'UserDriver.name as userdriver_name', 'UserDriver.phone_number as userdriver_phone_number'";
You could use with() to get associated drivers for a client
$client = ClientModel::where('id',$id)
->with('drivers:name,phone_number')
->get();
$clientDrivers = $client->drivers;
return response($clientDrivers, 200);

Categories