Retrieve data with relations in laravel - php

I would like to display the name of each entity in my table but it returns me
Property [name] does not exist on this collection instance.
My Controller
$users = User::with('pearls')->latest()->get();
the index.blade.php
<thead>
<tr>
<th scope="col">SL No</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
#foreach($users as $user)
<th>{{ $user->pearls->name}}</th>
#endforeach
<th scope="col">Actions</th>
</tr>
</thead>

Because pearls is a collection, not object!
I think you've performed a one-to-many relationship between user and pearl, so, you should use foreach for pearls too:
foreach ($user->pearls as $pearl){
echo $pearl->name;
}

The issue is this line: {{ $user->pearls->name}} in your blade.php
For hasMany relations you cant retrieve data like this.
Any relationship that has Many in it's name, example: hasMany or belongsToMany will always return a collection object.
Try dd($users->pearls), it'll return a collection of data.
You are trying to call the property name on a collection object, not from a singe model.
When you're using get() method you will get a collection. In this case you need to iterate over it to get properties.
#foreach ($user->pearls as $pearl)
{{ $pearl->name}}
#endforeach
By using its index you will get one of the object property
#foreach($users as $user)
<th>{{ $user->pearls[0]->name}}</th>
#endforeach
Or you can use the first() method instead of get() method in your query , so you can easily call the object property like {{ $user->pearls->name}} ,also you need to use one to one relation like hasOne.

Related

Attempt to read property "nama" on int

im trying to get the latest data on database, im using this on my views :
#foreach ($shows as $s)
<tbody>
<tr>
<th scope="row">{{$loop->iteration}}</th>
<td>{{$s->nama}}</td>
<td>{{$s->umur}}</td>
<td>{{$s->alamat}}</td>
<td>{{$s->nama_ortu}}</td>
<td>{{$s->posyandu}}</td>
<td>{{$s->result}}</td>
</tr>
</tbody>
#endforeach
and on controller :
public function showresultpasien()
{
$shows = DB::table('pasiens')->orderBy('id', 'DESC')->first();
return view('result', compact('shows'));
}
did i doin something wrong ?
The name of the function in the model cannot be the same as the name of a field in your table. Also in my case the column names do not follow the laravel/eloquent nomenclature so another parameter is added to belongsTo with the field name

Displaying total answer and correct answer of each user

I have a db structure like this:
Tables:
users(id, email, password, ...) //default laravel users table
examinees(id, user_id, ...)
exam_quizzes(id, title, explanation)
exam_quiz_answers(id, title, exam_quiz_id, is_correct_ans)
submitted_answers(id, user_id, exam_quiz_id, exam_quiz_answer_id)
I already have the respective models and relationship methods set up.
Models:
User, Examinee, ExamQuiz, ExamQuizAnswer, SubmittedAnswer
Relationships:
// User -> hasOne() -> Examinee
$user->examinee
// ExamQuiz -> hasMany() -> ExamQuizAnswer
$examQuiz->examQuizAnswers
// SubmittedAnswer -> hasMany() -> ExamQuiz
$submittedAnswer->examQuizzes
// SubmittedAnswer -> hasMany() -> ExamQuizAnswer
$submittedAnswer->examQuizAnswers
// User -> hasMany() -> SubmittedAnswer
$user->submittedAnswers
In my view, how can I display the Name, Total Answered and Total Correct for every user who is also an examinee, in a table like this:
<tr>
<th>Name</th>
<th>Answered</th>
<th>Correct</th>
</tr>
#foreach()
{{-- I have no idea what to do here --}}
<tr>
<td></td>
<td></td>
<td></td>
</tr>
#endforeach
In your controller, u get the users an pass it to view.
$users = User:get();
and the make a foreach loop to get the answer and correct answers:
<tr>
<th>Name</th>
<th>Answered</th>
<th>Correct</th>
</tr>
#foreach($users as $user)
<tr>
<td>{{$user->name}}</td>
<td>{{count($user->submittedAnswers()->get())}}</td>
#php
foreach($user->submittedAnswers()->get() as $answer){
foreach($answer->examQuizAnswers->get() as $quiz){
$count = $quiz->where('is_correct_answer',1)->count()
}
}
#endphp
<td>{{$count}}</td>
</tr>
#endforeach
But of course you can write a method in a model to retrieve the correct answers. and just call that method instead.
you can write a method like this in User model:
public function get_correct_answers($user_id){
$user = User::whereId($user_id)->first();
foreach($user->submittedAnswers()->get() as $answer){
foreach($answer->examQuizAnswers->get() as $quiz){
$count = $quiz->where('is_correct_answer',1)->count()
}
}
return $count;
}
And then in the view u just call that method like this:
<tr>
<th>Name</th>
<th>Answered</th>
<th>Correct</th>
</tr>
#foreach($users as $user)
<tr>
<td>{{$user->name}}</td>
<td>{{count($user->submittedAnswers()->get())}}</td>
<td>{{$user->get_correct_answers($user->id)}}</td>
</tr>
#endforeach
Loop your $users and echo the 3 fields you want. Something roughly like this:
{{ $user->name }}
{{ $user->submittedAnswers->examQuizAnswers()->where('is_correct_answer', 1)->get()->count() }}
{{ $user->submittedAnswers->examQuizAnswers->count() }}
But please don't actually query in view files for the sake of the children.
Eager load related models in your controller:
User::with(['submitted_answers', 'submitted_answers.exam_quiz_answers'])->get()

How to order my foreach in laravel blade

I am using a hasMany in my Model class to retrive the clients notes, how ever i want to order these notes by the latest date created in laravel blade template.
My code is below and im getting an error on this.
Please advice me..
#foreach($clients->notes->orderBy('created_at', 'desc') as $note)
<table class="table table-bordered">
<tr>
<td class="col-xs-2 col-md-2"><b>Created On:</b> {{ date('d/m/y', strtotime($note->created_at)) }} <b>#</b> {{ date('g:i A', strtotime($note->created_at)) }} </td>
<td class="col-xs-14 col-md-12">{{ $note->notes }}</td>
</tr>
</table>
#endforeach
Guessing, because you haven't told us what error you're getting, but:
$clients->notes is an already-fetched collection of results. $clients->notes() is a query builder that you can apply further logic like ordering or additional criteria to.
You likely want:
$clients->notes()->orderBy('created_at', 'desc')->get()
but you should do that in the controller and pass it to the view instead of having the query directly in the Blade template.
(You can alternatively use Laravel's collection functions on $clients->notes, including the sortBy() function).
Data must be ordered within controller or models. If you have used hasMany validation in model you can do as mentioned below
In model write association
public function notes()
{
return $this->hasMany('Note')->orderBy('created_at', 'desc');
}
In your controller function associate client with notes like this
$clients = Client::with('notes')->get();
Hope you get your answer

Trying to get property of non-object - Laravel 5

I'm trying to echo out the name of the user in my article and I'm getting the
ErrorException: Trying to get property of non-object
My code:
Models
1. News
class News extends Model
{
public function postedBy()
{
return $this->belongsTo('App\User');
}
protected $table = 'news';
protected $fillable = ['newsContent', 'newsTitle', 'postedBy'];
}
2. User
class User extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
protected $table = 'users';
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
}
Schema
table users
table news
Controller
public function showArticle($slug)
{
$article = News::where('slug', $slug)->firstOrFail();
return view('article', compact('article'));
}
Blade
{{ $article->postedBy->name }}
When I try to remove the name in the blade {{ $article->postedBy }} it outputs the id, but when I try to add the ->name there it says Trying to get property of non-object but I have a field namein my table and aUser` model. Am I missing something?
Is your query returning array or object? If you dump it out, you might find that it's an array and all you need is an array access ([]) instead of an object access (->).
I got it working by using Jimmy Zoto's answer and adding a second parameter to my belongsTo. Here it is:
First, as suggested by Jimmy Zoto, my code in blade
from
$article->poster->name
to
$article->poster['name']
Next is to add a second parameter in my belongsTo,
from
return $this->belongsTo('App\User');
to
return $this->belongsTo('App\User', 'user_id');
in which user_id is my foreign key in the news table.
If you working with or loops (for, foreach, etc.) or relationships (one to many, many to many, etc.), this may mean that one of the queries is returning a null variable or a null relationship member.
For example: In a table, you may want to list users with their roles.
<table>
<tr>
<th>Name</th>
<th>Role</th>
</tr>
#foreach ($users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ $user->role->name }}</td>
</tr>
#endforeach
</table>
In the above case, you may receive this error if there is even one User who does not have a Role. You should replace {{ $user->role->name }} with {{ !empty($user->role) ? $user->role->name:'' }}, like this:
<table>
<tr>
<th>Name</th>
<th>Role</th>
</tr>
#foreach ($users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ !empty($user->role) ? $user->role->name:'' }}</td>
</tr>
#endforeach
</table>
Edit:
You can use Laravel's the optional method to avoid errors (more information). For example:
<table>
<tr>
<th>Name</th>
<th>Role</th>
</tr>
#foreach ($users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ optional($user->role)->name }}</td>
</tr>
#endforeach
</table>
If you are using PHP 8, you can use the null safe operator:
<table>
<tr>
<th>Name</th>
<th>Role</th>
</tr>
#foreach ($users as $user)
<tr>
<td>{{ $user?->name }}</td>
<td>{{ $user?->role?->name }}</td>
</tr>
#endforeach
</table>
I implemented a hasOne relation in my parent class, defined both the foreign and local key, it returned an object but the columns of the child must be accessed as an array.
i.e. $parent->child['column']
Kind of confusing.
REASON WHY THIS HAPPENS (EXPLANATION)
suppose we have 2 tables users and subscription.
1 user has 1 subscription
IN USER MODEL, we have
public function subscription()
{
return $this->hasOne('App\Subscription','user_id');
}
we can access subscription details as follows
$users = User:all();
foreach($users as $user){
echo $user->subscription;
}
if any of the user does not have a subscription, which can be a case.
we cannot use arrow function further after subscription like below
$user->subscription->abc [this will not work]
$user->subscription['abc'] [this will work]
but if the user has a subscription
$user->subscription->abc [this will work]
NOTE: try putting a if condition like this
if($user->subscription){
return $user->subscription->abc;
}
It happen that after some time we need to run
'php artisan passport:install --force
again to generate a key this solved my problem ,
I had also this problem. Add code like below in the related controller (e.g. UserController)
$users = User::all();
return view('mytemplate.home.homeContent')->with('users',$users);
Laravel optional() Helper is comes to solve this problem.
Try this helper so that if any key have not value then it not return error
foreach ($sample_arr as $key => $value) {
$sample_data[] = array(
'client_phone' =>optional($users)->phone
);
}
print_r($sample_data);
Worked for me:
{{ !empty($user->role) ? $user->role->name:'' }}
In my case the problem was in wrong column's naming:
In model Product I've tried to access category relationship instance to get it's name, but both column name and relationship had the same name:
category
instead of:
category_id - for column name
category - for relationship
Setting up key name in relationship definition like
public function category():hasOne
{
return $this->hasOne(Category::class,'category');
}
didn't help because as soon as Laravel found property named category gave up on looking for relationship etc.
Solution was to either:
change property name (in model and database) or
change relationship name (Eg. productCategory )
It wasn't an error in my case. However, this happened to me when I was trying to open users.index, because while testing I've deleted some data from the 'STUDENTS' table and in the 'USERS' table, a foreign key ('student_id') represents the 'STUDENTS' table. So, now when the system tries to access the 'USERS' table in which foreign key ('student_id') is null since the value got deleted from the 'STUDENTS' table.
After checking for hours when I realise this, I insert the same data again in the 'STUDENTS' table and this resolved the issue.

Laravel Eloquent : belongsTo relationship - Error: Trying to get property of non-object

First time to try laravel eloquent relatioinstip
I know it's really simple but I am getting this error don't know what's wrong with it
I have 2 tables in data base, news and news_image
in database
Tables:
news
id | header | details
news_image
id | image | news_id
And have 2 models News , newsImage
newsImage model :
class newsImage extends Eloquant {
protected $table = 'news_image';
public function news()
{
return $this->belongsTo('News');
}
}
News model
class News extends Eloquent
{
protected $table = 'news';
public $timestamps = false;
public function image()
{
return $this->hasMany('newsImage');
}
}
The view:
foreach($news as $new)
<tr>
<td> {{$new->id}} </td>
<td> {{ $new->header}}</td>
<td> {{ $new->details }}</td>
</td> {{$new->news->image}}</td>
</tr>
when I run this it's get error :
Trying to get property of non-object (View: /var/www/html/clinics/app/views/news/index.blade.php)
Any ideas on what could be causing this error?
First, assuming what you are passing to your view is an array or Collection of News objects, you should probably be using $new->image to access the News Item relation. By defining the function image() in your News model, you can access the relation with either the ->image or ->image() calls. In either case, what you need to call is probably
$new->image->first()->image
To break that down:
->image gets the Collection of NewsImage relations
->first() gets the first item in the Collection
->image (the secone one) gets the image field from that NewsImage
If the Collection has more than one item, you can instead loop over it to get all of the images as shown in the other answer.
There are a couple things I would change:
In your News model, change the relationship from "image" to "images" since it's a one to many relationship. It just keeps your code clean.
Your foreach loop in your view should loop through all the news models, but remember that each news model has multiple images, so you should have another loop inside your existing loop to display the images, i.e. foreach ($new->images as $image)
#foreach ($news as $new)
<tr>
<td> {{$new->id}} </td>
<td> {{ $new->header}}</td>
<td> {{ $new->details }}</td>
<td>
#foreach ($new->images as $image)
{{ $image->image }}
#endforeach
</td>
</tr>
#endforeach

Categories