How to access a particular attribute in a Collection? - php

I want to access the name attribute from the practice table but I am getting Collections. My code looks like.
$practice = Practice::withTrashed()->where('id',$appointment->practice_id)->get();
dd($practice);
and result looks like
Collection {#697
#items: array:1 [
0 => Practice {#698
#dates: array:1 [
0 => "deleted_at"
]
#fillable: array:2 [
0 => "name"
1 => "email"
]
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:7 [
"id" => 42
"name" => "DJ and Charlie Eye Associates"
"email" => "vendorsupport#ocuhub.com"
"created_at" => "0000-00-00 00:00:00"
"updated_at" => "2017-01-13 06:29:14"
"liferay_id" => 57238
"deleted_at" => "2017-01-13 06:29:14"
]
#original: array:7 [
"id" => 42
"name" => "DJ and Charlie Eye Associates"
"email" => "vendorsupport#ocuhub.com"
"created_at" => "0000-00-00 00:00:00"
"updated_at" => "2017-01-13 06:29:14"
"liferay_id" => 57238
"deleted_at" => "2017-01-13 06:29:14"
]
#relations: []
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [
0 => "*"
]
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
#forceDeleting: false
}
]
}
Is there any way to do , so I can get the name "DJ and Charlie Eye Associates". I used withThrashed method because this entry is soft deleted in the practice table.

First you need to get an object from a collection and then you can get any property of that object:
$practice->first()->name;
Or:
$practice[0]->name;

You can Either use foreach loop
foreach($collection as $collect){
dd($collect->name);
}
or you can just convert the collection into array
$array = $collection->toArray();
dd($array[0]->name);
or
$collection->first()->name;
Hope This Helps You.
Ask if any query

You could simply get this by using this
dd($practice[0]->name);
Or if you know that your query will return only one object you could use ->first() in place of ->get() and then you could use.
dd($practice->name);
->first() gives first object
->get() gives array of objects.

$practice = Practice::withTrashed()->where('id',$appointment->practice_id)->get()->get('name');
dd($practice);
Though this is incredibly ugly and you probably read up on Collections: your statement is doing exactly what Laravel says it does.
https://laravel.com/docs/5.3/collections

Use find() if id is the primary key, you will get just the Practice back.
$practice = Practice::withTrashed()->find($appointment->practice_id);
https://laravel.com/docs/5.3/eloquent#retrieving-single-models

Related

Laravel update() not working in a foreach even though I have declared $fillable

I have some rather ugly code here:
foreach($request->assigned['standards'] as $standard){
if(#$standard['plannings']) {
foreach($standard['plannings'] as $p) {
dump($p['id']);
$assigned = PerformanceManagementSetModuleStandardAssignedPlanning::
where('id', $p['id'])
->where('performance_management_set_assigned_id', $request->assigned_id)
->first();
$assigned->text = $p['text'];
$assigned->user_id= 1; //I did this to check that the model was updating, it was
dump($assigned);
$assigned->update();
}
}
}
The record is updating, everything apart from the "text" column. I manually updated the "user_id" column just to make sure, and this updates perfectly fine.
I have text as a fillable property:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class PerformanceManagementSetModuleStandardAssignedPlanning extends Model
{
use HasFactory;
protected $fillable = [
'text',
];
}
It can also be seen here when I dump ( dump($assigned) ):
App\Models\PerformanceManagementSetModuleStandardAssignedPlanning {#1611
#fillable: array:1 [
0 => "text"
]
#connection: "mysql"
#table: "performance_management_set_module_standard_assigned_plannings"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:7 [
"id" => 307
"performance_management_set_module_standard_id" => 92
"performance_management_set_assigned_id" => 110
"user_id" => 233
"text" => "134523453452345345234123"
"created_at" => "2022-05-12 10:06:24"
"updated_at" => "2022-05-12 10:28:14"
]
#original: array:7 [
"id" => 307
"performance_management_set_module_standard_id" => 92
"performance_management_set_assigned_id" => 110
"user_id" => 233
"text" => null
"created_at" => "2022-05-12 10:06:24"
"updated_at" => "2022-05-12 10:28:14"
]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [
0 => "*"
]
}
Is there something simple I'm missing here?
You can use save() method for that update.
foreach($request->assigned['standards'] as $standard){
if(#$standard['plannings']) {
foreach($standard['plannings'] as $p) {
$assigned = PerformanceManagementSetModuleStandardAssignedPlanning::
where('id', $p['id'])
->where('performance_management_set_assigned_id', $request->assigned_id)
->first();
$assigned->text = $p['text'];
$assigned->user_id= 1; //I did this to check that the model was updating, it was
$assigned->save();
dump($assigned);
}
}
}
Turns out the loop what overwriting, the same ID was being passed each time. Thanks for all your help!

Get particular values multidimensional array Laravel

I want to get the values of some fields form the #attributes field (like "title" and "location") so I can fill a calendar.
dd($events); Outputs:
Illuminate\Database\Eloquent\Collection {#948 ▼
#items: array:3 [▼
"26-01-2021" => Illuminate\Database\Eloquent\Collection {#972 ▶}
"01-02-2021" => Illuminate\Database\Eloquent\Collection {#962 ▶}
"03-11-2021" => Illuminate\Database\Eloquent\Collection {#965 ▼
#items: array:1 [▼
0 => App\Models\DaysEvent {#994 ▼
#table: "days_events"
#casts: array:11 [▶]
#dates: array:2 [▶]
#fillable: array:25 [▶]
#dispatchesEvents: array:1 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:29 [▼
"id" => 166
"title" => "Individual Interview"
"slug" => "individual-interview"
"functionality_type" => "selection"
"days_event_type_id" => 1
"event_start" => "2021-11-03 09:00:00"
"event_end" => "2021-11-03 19:00:00"
"location" => "Online"
"excerpt" => "Suit up and sit down with a recruiter to get in touch with the company on an individual level."
"content" => "<div>Suit up and sit down with a recruiter to get in touch with the company on an individual level. The Individual Interview will last 30 or 50 minutes and is e ▶"
"event_link" => "https://zoom.us/j/1234"
"parent_event_id" => null
"requires_motivation" => 1
"requires_cv" => 1
"requires_followup" => 1
"requires_student_company_preference" => 0
"company_id" => 34
"force_in_calendar" => 0
"spots" => 9
"has_timeslots" => 1
"has_algorithm_priority" => 1
"timeslot_slots" => "["9:00-9:30","9:30-10:00","10:00-10:30","11:00-11:30","11:30-12:00","12:00-12:30","13:00-13:30","13:30-14:00","14:00-14:30"]"
"timeslot_people" => 1
"can_unsubscribe_late" => 1
"company_can_see_cvs" => 1
"sf_id" => null
"deleted_at" => null
"created_at" => "2021-01-04 10:33:38"
"updated_at" => "2021-11-16 12:33:00"
]
#original: array:29 [▶]
#changes: []
#classCastCache: []
#dateFormat: null
#appends: []
#observables: []
#relations: array:1 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
]
#escapeWhenCastingToString: false
}
]
#escapeWhenCastingToString: false
}
I think I can get the values using the collect function form Laravel. (read this on this very similar question)
But when I try do do: $event_items = collect($events->items);
It gives the error: Property [items] does not exist on this collection instance.
What am I doing wrong here?
you are not get direct use of item,
you use $event_items = collect($events['03-11-2021']['0']->title);
This result you have is basically a collection of collections of models. Collections implement array access so you can user $collection['index'] or you can use $collection->get('index'). If you want all the values in the collection you can call the $collection->all() method. I don't really understand what data you want to get from here or why you have a collection of collections in the first place but the $collection->map() or $collection->transform() method is usually used to extract specific data from a collection.
I also believe that $collection->items is a private property so if you want all the items it is the same as $collection->all()
You can check Collections documentation for how they work.

Laravel fetch all the values of a column

The user_enabled_notifications table has 2 rows of data. i wanted to fetch all the values in the id column.
$notificationData = UserEnabledNotifications::all();
dump($notificationData['id']); shows Undefined index: id
dump($notificationData->id); shows Property [id] does not exist on this collection instance
dump($notificationData[0]['id']); shows only 1 id. What else shall i try to fetch all the id column values in a single stretch.
However, dump($notificationData); shows the complete data in table as given below.
Illuminate\Database\Eloquent\Collection {#337
#items: array:4 [
0 => App\Models\UserEnabledNotifications {#338
#table: "user_enabled_notifications"
#fillable: array:3 [
0 => "userId"
1 => "notificationTypesId"
2 => "status"
]
#connection: "pgsql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:7 [
"id" => 1
"userId" => 1
"notificationTypesId" => 1
"status" => true
"deleted_at" => null
"created_at" => null
"updated_at" => null
]
#original: array:7 [
"id" => 1
"userId" => 1
"notificationTypesId" => 1
"status" => true
"deleted_at" => null
"created_at" => null
"updated_at" => null
]
#changes: []
#casts: array:1 [
"deleted_at" => "datetime"
]
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [
0 => "*"
]
#forceDeleting: false
#enableLoggingModelsEvents: true
#oldAttributes: []
}
1 => App\Models\UserEnabledNotifications {#339
#table: "user_enabled_notifications"
#fillable: array:3 [
0 => "userId"
1 => "notificationTypesId"
2 => "status"
]
#connection: "pgsql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:7 [
"id" => 2
"userId" => 1
"notificationTypesId" => 2
"status" => true
"deleted_at" => null
"created_at" => null
"updated_at" => null
]
#original: array:7 [
"id" => 2
"userId" => 1
"notificationTypesId" => 2
"status" => true
"deleted_at" => null
"created_at" => null
"updated_at" => null
]
#changes: []
#casts: array:1 [
"deleted_at" => "datetime"
]
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [
0 => "*"
]
#forceDeleting: false
#enableLoggingModelsEvents: true
#oldAttributes: []
}
The $notificationData is an object of type Illuminate\Database\Eloquent\Collection, a collection. If you want to get the id of individual elements. Pls do the followings:
foreach ($notificationData as $notification) {
dump($notification->id);
}
// Or
$notificationData->pluck('id')->toArray();
Try this
// get your main collection with all the attributes...
$notificationData = UserEnabledNotifications::get();
// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not UserEnabledNotifications models.
$subset = $notificationData->map(function ($notification) {
return collect($notification->toArray())
->only(['id'])
->all();
});
dd($subset);
OR
$notificationData = $notificationData->pluck('id')->toArray();
dd($notificationData);
all() gives you an collection (similar to array), so it has index (0 and positive integers) for keys
use pluck() to get all specific value for a key
$notificationData = UserEnabledNotifications::pluck('id');
print($notificationData) // [1, 2, 3, 4, 5, 6, ...]

How to get a single value from Query Builder in Laravel?

I'm trying to get a single value from Query Builder in Laravel but the problem is I'm getting an array.
this is my query result in Postman with dd($myVar):
[{"is_liked":1}]
and also with echo($myVar):
Collection {#976
#items: array:1 [
0 => NewsCommentLike {#970
#fillable: array:3 [
0 => "user_id"
1 => "news_comment_id"
2 => "is_liked"
]
#connection: "mysql"
#table: "news_comment_likes"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:1 [
"is_liked" => 1
]
#original: array:1 [
"is_liked" => 1
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [
0 => "*"
]
}
]
}
and my code is:
$previous_is_liked = NewsCommentLike::query()->where(['user_id' => $user_id, 'news_comment_id' => $newsComment->id])->get(['is_liked']);
How to get a single value from is_liked not an array?
This is why you have ->value('my_column') method. So you'll end up with:
NewsCommentLike::query()
->where(['user_id' => $user_id, 'news_comment_id' => $newsComment->id])
->value('is_liked');
The advantage is that the value is retrieved directly from the database. If you call first() before it, it can be null thus break your code.
$previous_is_liked = NewsCommentLike::query()->where(['user_id' => $user_id, 'news_comment_id' => $newsComment->id])->first()->is_liked;
Calling first returns 1 result instead of an array, then you can call the column you want.
I believe you could also call it like this:
$previous_is_liked = NewsCommentLike::query()->where(['user_id' => $user_id, 'news_comment_id' => $newsComment->id])->first()->value('is_liked')

Laravel Unit Testing Inconsistency

Hi I am following the laravel course from laracast, but faced some difficulty following the course.
In the app, there is a Post Model with a static function that returns grouped records:
Post.php
public static function archives()
{
return static::selectRaw('year(created_at) as year, monthname(created_at) month, count(*) published')
->groupBy('year', 'month')
->orderByRaw('min(created_at) desc')
->get()
->toArray();
}
On the other hand, a test case aims to test the Post::archives() function:
ExampleTest.php
public function testBasicTest()
{
// GIVEN I have two records in the database that are posts,
// and each one is posted a month apart.
$first = factory(Post::class)->create();
$second = factory(Post::class)->create([
'created_at' => \Carbon\Carbon::now()->subMonth()
]);
// WHEN I fetch the archives
$posts = \App\Post::archives();
// dd($posts);
// THEN the response should be in the proper format
$this->assertEquals([
[
"year" => $first->created_at->format('Y'),
"month" => $first->created_at->format('F'),
"published" => 1
],
[
"year" => $first->created_at->format('Y'),
"month" => $first->created_at->format('F'),
"published" => 1
],
], $posts);
}
However, the assertion failed, because $posts is an array of object instead of an array of array, even though Post::archives() specifically converted the results with toArray().
Dumping it on tinker:
$posts = \App\Post::archives()
[
[
"year" => 2014,
"month" => "March",
"published" => 2,
],
[
"year" => 2014,
"month" => "February",
"published" => 1,
],
[
"year" => 2013,
"month" => "February",
"published" => 1,
],
]
The error on phpunit
1) Tests\Unit\ExampleTest::testBasicTest
Failed asserting that two arrays are equal.
--- Expected
+++ Actual
## ##
Array (
- 0 => Array (...)
- 1 => Array (...)
+ 0 => App\Post Object (...)
+ 1 => App\Post Object (...)
)
dd($posts) derives:-
..array:2 [
0 => App\Post {#863
#guarded: []
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:3 [
"year" => 2018
"month" => "April"
"published" => 1
]
#original: array:3 [
"year" => 2018
"month" => "April"
"published" => 1
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
}
1 => App\Post {#864
#guarded: []
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:3 [
"year" => 2018
"month" => "March"
"published" => 1
]
#original: array:3 [
"year" => 2018
"month" => "March"
"published" => 1
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
}
]
Why is it behaving as such in the TestCase?
While it might be extra labor, and I can't exactly tell you why it happens, you might want to explicitly call the attributes in an outside array, as in:
$postsArray = [
"year" => $posts->year,
"month" => $posts->month,
"published" => $posts->published
];
I think the reason it is doing that is because it first creates the model object and then attempts to access the query search, and for whatever reason it simply returns the object instance. I would need to read a little more before giving a good conclusion. I was going to say that it might just be failing to find anything with the query and thus returning the object itself, but I haven't actually ever used a model search that way so I can't say with precision that's what happens.

Categories