Find child by ID from collection of parent laravel - laravel

I have Parent - Child relationship
Parent Model
public function child() {
return $this->hasMany(Child::class);
}
Child Model
public function parent() {
return $this->belongsTo(Parent::class);
}
App
I am getting the parent collection which I am using elsewhere
$this->parent = Parent::where('active', true)->with('child')->get()
The Problem
I have a on-click function where i'm getting just the ID of the child. So i'm trying to find the child in the parent collection.
public function click($id) {
$child = $this->parent->child()->find('id', $id)->first();
}
Error -
Method Illuminate\Database\Eloquent\Collection::child does not exist.
Is it possible to get the child from the existing collection, I know I could do another db query but really not wanting to make another query as I already have the data just there.
$this->parent->toArray()
array:2 [▼
0 => array:11 [▼
"id" => 1
"active" => 1
"name" => "Foo"
"child" => array:3 [▼
0 => array:3 [▼
"id" => 1
"parent_id" => 1
"name" => "S/M"
]
1 => array:3 [▼
"id" => 2
"parent_id" => 1
"name" => "L/XL"
]
2 => array:3 [▼
"id" => 3
"parent_id" => 1
"name" => "2XL"
]
]
]

You can use where condition to find using child id
$this->parent->where('child.id', $id)->first()
if you are looking to find parent id then
$this->parent->find($id)
you have hasmany data so
$this->parent->filter(function ($value)use($id){
return $value->child->find($id);
})->first();

Related

Laravel Microsoft Graph request how to solve Cannot use object of type?

I try to do a graph request in my laravel project to connect Microsoft API. All works fine, but I don't find a way to get single data from my request.
$info = $graph->createRequest("GET", "/groups/{id}/calendar/events?\$filter=start/dateTime ge '" . $todayDate . "T00:00' and end/dateTime lt '" . $todayDate . "T23:00'")
->addHeaders(array("Content-Type" => "application/json"))
->setReturnType(\Microsoft\Graph\Model\User::class)
->setTimeout("1000")
->execute();
Output is a large json with all information. If I just want to get $info[0]['attendees'];
I get error: Cannot use object of type Microsoft\Graph\Model\User as array in file
Why? And how to access? If I try load object like $info->attendees I got error: Trying to get property 'attendees' of non-object.
This is my output (not all) of dd($info) it includes attendees as array like "id"
array:10 [▼
0 => Microsoft\Graph\Model\Event {#1532 ▼
#_propDict: array:43 [▼
"#odata.etag" => "{tag}""
"id" => "{id}"
"createdDateTime" => "2021-03-19T10:36:08.0812445Z"
"lastModifiedDateTime" => "2021-03-19T10:36:11.9402917Z"
"attendees" => array:1 [▼
0 => array:3 [▼
"type" => "required"
"status" => array:2 [▶]
"emailAddress" => array:2 [▼
"name" => "name"
"address" => "mail"
]
]
]
It seems your array is returning an array of attendees, you have an extra level in your array. So to fetch the first attendees status, you need to use the following code:
Try this
foreach($info as $item){
foreach($item as $inf ){
$a = $inf->status
dd($a)
}
}

Laravel belongsto relations get property problem

I have belongsto relation:
class Yetkiliservis extends Model
{
protected $table = 'yetkiliservis';
protected $guarded=[];
public function bolge(){
return $this->belongsTo(Bolgeler::class);
}
}
when I convert the model to array everything is right. It shows relation.
$yetkiliservisler = Yetkiliservis::with('bolge')->get();
dd($yetkiliservisler[0]->toArray());
result :
array:22 [▼
"id" => 1
"vergi_no" => "1"
"yerel_adi" => "1"
"bolge" => array:6 [▼ <------------------------------------
"id" => 1
"bolge_adi" => "İSTANBUL"
"ad_soyad" => "istanbul"
"email" => "istanbul#mail.com"
"created_at" => "2020-04-24 15:53:31"
"updated_at" => "2020-04-24 15:53:31"
]
"yetkili_adi" => "1"
]
But when I try to get by the property it shows null.
$yetkiliservisler = Yetkiliservis::with('bolge')->get();
dd($yetkiliservisler[0]->getAttributes());
result :
array:22 [▼
"id" => 1
"vergi_no" => "1"
"yerel_adi" => "1"
"bolge" => null <--------------------------------
"yetkili_adi" => "1"
]
First you change the raname like this
public function bolges(){
return $this->hasMany(Bolge::class,'yetkiliservi_id','id');
}
After you execute this command
composer dump-autoload
Then first check php artisan tinker; relation is correct??
Then try this
$yetkiliservisler[0]->bolges;
Hope it will helpful for you

Laravel resource ignoring given fields

I'm trying to convert a given API response in something easy to work with.
This is what I have so far:
Controller:
public function drive()
{
$optParams = [
'corpora' => 'drive',
'driveId' => env('GOOGLE_DRIVE_ID'),
'includeItemsFromAllDrives' => true,
'supportsAllDrives' => true,
'fields' => 'files(*)'
];
$results = $this->googleDrive->files->listFiles($optParams);
$data = collect($results);
$collection = new FileCollection($data);
dd($collection);
return 'Hi!';
}
FileCollection resource:
public function toArray($request)
{
return [
'data' => $this->collection,
'meta' => ['files_count' => $this->collection->count()],
];
}
File resource:
public function toArray($request)
{
return [
'name' => $this->resource['name'],
'mime' => $this->resource['mimeType'],
'parents' => $this->resource['parents'],
'version' => $this->resource['version'],
'webDownloadLink' => $this->resource['webContentLink'],
'webLink' => $this->resource['webViewLink'],
'modified_at' => $this->resource['modifiedTime'],
'size' => $this->resource['size']
];
}
This is the result I'm getting:
FileCollection {#223 ▼
+collects: null
+collection: Collection {#243 ▶}
+resource: Collection {#243 ▼
#items: array:2 [▼
0 => File {#224 ▼
+resource: Google_Service_Drive_DriveFile {#279 ▶}
+with: []
+additional: []
}
1 => File {#263 ▼
+resource: Google_Service_Drive_DriveFile {#269 ▶}
+with: []
+additional: []
}
]
}
+with: []
+additional: []
}
So as you can see the types of resources are correct, but for some reason the 'meta' in the FileCollection isn't there, nor are the fields in the File resource. All fields are still shown, like 30+ (instead of the 8 requested in the FileResource).
Am I missing something here?
EDIT:
When accessing the collection with the toArray() method ($collection->toArray(null)), I do indeed get the appropriate result:
array:2 [▼
"data" => Collection {#243 ▼
#items: array:2 [▼
0 => File {#224 ▶}
1 => File {#263 ▶}
]
}
"meta" => array:1 [▼
"files_count" => 2
]
]
So how do I make sure now that this collection uses the toArray() of the FileResources? (I'm still getting over 30 fields, instead of 8).
PS: I don't really get why I need to call the toArray(), nowhere in their documentation is it written : https://laravel.com/docs/5.8/eloquent-resources .

use sync method for an array and also add extra pivot fields?

This is my input array
"events" => array:2 [▼
"special-date" => array:3 [▼
0 => "14-Nov-1979"
1 => "18-Apr-1981"
2 => "12-Nov-1978"
]
"event" => array:3 [▼
0 => "2"
1 => "3"
2 => "4"
]
]
This is my code
$User->events()->sync($request->events['event'], ['event_date' => $request->events['special-date']]);
here, $user is an instance of the user model
This is my user model realtion function
public function events()
{
return $this->belongsToMany('App\Models\Event', 'user_events', 'user_id', 'event_id')->withPivot('event_date');
}
and I got an error of event_date has no default value.
my table structure of a user_event table is
id,
user_id,
event_id,
event_date

Get relation of relation

I'm trying to get the comments of the links with laravel relationship, the comments of links return normally, but I don't know how to get it in view or dd(), how can I do it?
Controller:
$page = Page::where('friendly_url', $id)
->select('id', 'photo', 'friendly_url', 'name', 'description', 'followers', 'links', 'tag_id', 'links_clicks')
->with('ptag', 'links', 'links.comments', 'links.tag')
->with(['links.comments.user' => function($query) {
$query->select('id', 'name', 'lastname');
}])->with(['links.comments.userProfile' => function($query) {
$query->select('id', 'photo');
}])->first();
dd($page->getRelation('links')
Collection {#301 ▼
#items: array:2 [▼
0 => Link {#307 ▼
#relations: array:2 [▼
"comments" => Collection {#316 ▼
#items: array:1 [▶]
"tag" => Tag {#322 ▶}
]
dd($page->getRelation('links')->getRelation('comments'))
BadMethodCallException
Method getRelation does not exist.
dd($page->getRelation('links')->comments)
Exception
Property [comments] does not exist on this collection instance.
EDIT:
I want to show the attributes of comment and comment.user, how I can do it?
foreach($page->getRelation('links')->pluck('comments') as $comment) {
dd($comment);
}
Collection {#327 ▼
#items: array:1 [▼
0 => Comment {#325 ▼
#attributes: array:5 [▼
"id" => 3
"content" => "teste"
"link_id" => 1
"user_id" => 1
"created_at" => "2018-01-11 00:47:32"
]
#relations: array:2 [▼
"user" => User {#330 ▼
#attributes: array:3 [▼
"id" => 1
"name" => "Halysson"
"lastname" => "Teves dos Santos"
]
}
"userProfile" => UserProfile {#326 ▶}
]
Try this-
foreach($page->links as $link){
$comments = $link->comments;
}
You should define relations first on relevent models and then using 'with' function can load models with relations OR a relation can be called directly by single model see documentation for further details
eg: you have defined a relation for user to phone, as user has a phone, one to one relation. in user model define a relation like
public function phone()
{
return $this->hasOne('App\Phone');
}
now to call this relation on user model instance.
$user = User::find(1);
dd($user->phone);
Because you're using the select() method, you also need to include all the foreign keys in it to allow Eloquent to be able to load these relationships.
But since you just start using Laravel, I'd recommend you to just remove select() method from this complex query.
If you want the links of a page :
$page->links
if you want all the comments of a page :
$page->links->pluck('comments')
that's it :)

Resources