Laravel Scout issue with relationship - laravel

Using Laravel scout I want to delete a record (on an Agent model), everything works well except that I'm redirecting to a list of agents after the delete, and since the queue is yet to be processed the deleted agent comes back from Meilisearch, but the Eloquent model doesn't exist anymore, resulting in an error Attempt to read property "id" on null :
// getting agents to display in the view
Agent::search($this->search)
->orderBy('id', 'asc')
->paginate($this->perPage)
// showing an agent ID in a loop in the view
{{ $agent->user->id }}
If reloading the page the list is fine - the deleted user has successfully been deleted. How can I prevent this error?

It surprises me that scout contains the null values in the collection...
However, you can run a ->filter() (docs) on the returned collection to remove all null results in it:
Agent::search($this->search)->get()->filter();
The collection now does not contain any null values

Related

Accessing eager-loaded objects in view laravel 5.7

i have several models that are linked to one model Call
i have all the relationships defined and they work pretty okay but i have issues with eager loaded results.
i have this query:
$callDetails =\App\Call::with(['client','subissues','subissues.issue','partner','district'])
->where('call.id', '=', $id)
->get();
that works fine in tinker returning
{"id":17400,
"client":{"id":18317,"name":"Yad Kal","phonenumber":"0991234567","age":27,"gender":"Male"},
"district":{"id":1,"name":"Dedza"},
"comments":" He complained ",
"completeness":"complete",
"perpetrator":1,
"partner_id":119,"status":1,
"subissues":[{"id":1378,"name":"Issues of Dissatifaction","description":"Issues of Dissatifaction","issue":{"id":6,"name":"Emergency Response (World)","description":"Emergency response"},"pivot":{"call":17400,"subissue":1378}}],"partner":{"id":119,"name":"World"}}
but when trying to access client with $callDetails->client, it returns the client id only.
and $callDetails->client->name returns an error.
i don't know what am doing wrong but all the eagerloaded results are giving me headaches!
Make sure you don't have in your table column with name client or you don't have any property in your model with name client. When relationship and field/property has exact same name (in your case client) it might cause problems, so in such case you should rename either relationship or field/property

How to display in blade which rows are soft deleted?

I have created a polling system and in the backend (CMS area) I want the ability for admins to be able to remove polls. When an admin removes a poll, it should soft delete the poll. This is working as intended, however I also want to have the ability for the admin to be able to restore a poll. To do this I am displaying all of the polls (including the soft deleted polls) in the admin area.
PollController index() to get all polls
$polls = Poll::withTrashed()->get();
In the blade I want to have two different buttons for each poll. One of restoring and one for deleting but I only want to display 1 button for each poll depending on whether it can be restored or deleted.
To do this, I have put this inside the foreach in the blade:
#if($poll->trashed())
// Restore button
#else
// Delete button
#endif
However the issue is, trashed() keeps returning true for all the polls when only 1 out of the 3 polls I have are actually soft deleted. I am unsure as to why trashed() returns all of these are true?
How would I get this method working correctly? Thanks.
PART 1
It depends on your query. When using soft deletes, Laravel will query all models that are not soft-deleted by default. When you also want to get the soft-deleted models, you need to call the withTrashed() method on your query. Read more here:
https://laravel.com/docs/5.5/eloquent#querying-soft-deleted-models
To understand what withTrashed() does, you need to understand how soft-deleting works. Soft-deleting models works by adding a new column to your database tables called deleted_at. It's value defaults to null. When you soft-delete a model, Laravel will put the current timestamp into that column. Therefore, this field doesn't contain a null value anymore.
When querying models when using soft-deletes, Laravel appends a deleted_at is null condition to the query. Calling the withTrashed() method, removes that condition from the query.
Have a look on the source of the default query modifier and the withTrashed method.
PART 2
That are events. You can call that to tell Laravel, that it should execute that specific closure when this event happens. In your example, it is listening for the "deleting" event. See more on that here:
https://laravel.com/docs/5.5/eloquent#events
PART 3
You can entirely delete soft-deletable models with the forceDelete() method. See "Permanently Deleting Models" here:
https://laravel.com/docs/5.5/eloquent#querying-soft-deleted-models
FOR EXAMPLE
$items = App\Model::withTrashed()->get();
If you want to restore a single item, just find it by ID:
$item = App\Model::find($id);

Vue.js - Laravel User Id

Im working on a project to learn Vue.js with Laravel.
I created a simple tasks application, where its possible to create, modify, mark as done, and delete tasks.
I wish to make it user individual, so i ran artisan make:auth to create the auth template.
Added column : user_id to tasks table.
In the Index method of TaskController instead of -
return Task::all();
I tried to do -
return Task::where('user_id', Auth::id() );
but its not working as I wish...
If instead of Auth::id() I put 1 for example, it does return the tasks for user id 1.
Can anyone help me out?
Check in your code that Auth::id() is actually returning the user's ID - it's likely that your user isn't authenticated and is therefore returning null, so the query doesn't work as you expect.
Also, if you set up your associations correctly (that is, a user hasMany tasks) then you could simplify the code by using the association instead.
return Auth::user()->tasks;
// Achieves same result as...
return Task::where('user_id', Auth::id())->get();

Laravel passing variable from multiple models

I have 2 models
User
Customer
Each user hasMany customers (aka Accounts)
the user model has
public function customer() {
return $this->hasMany('App\Customer', 'id','customer_id');
}
but when i try to output this:
$user->customer->name
i get an error saying:
Undefined property: Illuminate\Database\Eloquent\Collection::$name
When i use this one, i get the entire customers record output in JSON.
$user->customer
So the relationship is working, but obviously i am missing something. I was sure this was the right way to do it. I swear this worked in Laravel4.2 but now that I'm in Laravel 5 it doesn't.
As the error and the below link says, It is returning a collection (hasMany) not a single object, you need to either loop over the collection or do direct access in the collection based on the index.
that is to say... does doing this work?..
$user->customer[0]->name
http://laravel.io/forum/04-10-2014-undefined-property-illuminatedatabaseeloquentcollectionitem
You should loop over customers, if you want display customers in laravel view you can do the following
#foreach
($user->customer as $cust)
{{$cust->name}}
#endforeach

laravel checking pivot returns error contains() on a non-object

Background:
What I am doing is I have made a page displaying a table with checkboxes for attendees and events. It was working until I tried to check my checkboxes based on a query through a pivot table through a belongs to many relation.
I have looked at some other threads and tried the same approach to check a pivot for existing entry data. I am using the contains() function to see if my attendee and scheduled_program_segment are matched, but for some reason my code gets this error.
Problem:
I get the error Call to member function contains() on a non-object.
Here is the bit of my code I think is relevent
#foreach( Auth::user()->attendee as $attendee )
<td class="col-lg-1">
{{
Form::checkbox(
($program->name . $attendee->first_name),
'1',
$attendee->scheduled_program_segments->contains($attendee->id)
)
}}
I tried changing to $attendee as well. Same error.
Also, when I run
{{$attendee->scheduled_program_segments()->get()}}
I get the following which I am assuming means I have the pivot table and model set up correctly, but it's not working so maybe I am wrong here.
[{"id":"1","created_at":"2014-11-14 15:19:44","updated_at":"2014-11-14 15:19:44","name":"Minecraft","description":"","date":"2014-11-06","cost":"20.00","start_time":"16:30:00","end_time":"17:30:00","location":"Cookstown","scheduled_program_id":"1","program_segment_id":"1","pivot":{"attendee_id":"1","scheduled_program_segment_id":"1"}},{"id":"1","created_at":"2014-11-14 15:19:44","updated_at":"2014-11-14 15:19:44","name":"Minecraft","description":"","date":"2014-11-06","cost":"20.00","start_time":"16:30:00","end_time":"17:30:00","location":"Cookstown","scheduled_program_id":"1","program_segment_id":"1","pivot":{"attendee_id":"1","scheduled_program_segment_id":"1"}}]
$attendee->scheduled_program_segments
is a m-m relation, so obviously it returns null, because Laravel 4+ relations need to be camelCased in order to work as dynamic properties (that is what you're trying to do).
So you can either rename your relation to scheduledProgramSegments() and then call it:
$attendee->scheduledProgramSegments
// or
$attendee->scheduled_program_segments // yes, this will work as well
or change that line as follows (which I'd rather not suggest):
$attendee->scheduled_program_segments()->get()->contains(...)

Resources