Property [name] does not exist on this collection instance. Eloquent Laravel - laravel

I have a potentially basic problem for Eloquent. I want to show only the name corresponding with Role of that user. I used the Eloquent Relationship ManytoMany. But I can't get that to work.
I tried point to the name using the $users parameter but this didn't work.
My project has three files such as Role model, StudentController, find_username view.
Thank you.
Role Model:
class Role extends Model
{
protected $fillable = ['id','role_name','role_level','role_note'];
public function users()
{
return $this->belongsToMany('App\User', 'role_users', 'user_id', 'role_id');
}
}
My StudentController:
class StudentController extends Controller
{
public function find_username()
{
$roles = Role::all();
foreach($roles as $role)
{
echo $role->users . '<br>';
}
return view('find_username',['roles'=> $roles]);
}
}
My find_username view:
#extends('master')
#section('content')
<div class="row">
<table class="table">
<thead>
<tr>
<th>ID Role</th>
<th>Role name</th>
<th>Role level</th>
<th>Role note</th>
<th>User name</th>
</tr>
</thead>
<tbody>
#foreach ($roles as $item)
<tr>
<td>{{$item['id']}}</td>
<td>{{$item['role_name']}}</td>
<td>{{$item['role_level']}}</td>
<td>{{$item['role_note']}}</td>
<td>{{$item->users}}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
#endsection

You have many roles. Each of these roles have many users. Your table will be fine as it is to show the name of the role, roll level, and role note, because these are on the looped $item variable individually.
The problem is that while the $item holds those singular fields, the $item->users is another collection of user objects. Which means you have added another dimension onto your table. You might have 1 or 100 users to fit inside that <tr>.
To demonstrate, try this code, specifically adding in all the users names (adding the parameter to each user object in a new loop):
#foreach ($roles as $item)
<tr>
<td>{{$item['id']}}</td>
<td>{{$item['role_name']}}</td>
<td>{{$item['role_level']}}</td>
<td>{{$item['role_note']}}</td>
#foreach($item->users as $user)
<td>
{{$user->name}}
{{$loop->last?"":" | "}} //<-- just to separate names for this test
</td>
#endforeach
</tr>
#endforeach
If you have your models and relations set up correctly, this will show you your users for each role. However, as you can see, this may not be the best way to display this data. You might have dozens of users per role. You may wish to consider making a totally separate table for each role's users. Maybe click on something for the role on this table and bring up a new list or table of those users who have the role.
HTH

Related

How to get the counts of Student for each Teachers in a single collection by Eloquent

A Teacher has many Students. When I am showing the Teachers list I also want to show the counts of Student for each Teachers. How can I do this by using Eloquent?
I can find the Teachers from this,
$teacher= Teacher::where('teacher_status','active')->get();
I can find the Student count from this
$student_count = Student::where('teacher_id','teachers.id')->count();
How can I conbine this two query and return the response in a single array/collection?
In your teacher model, create the relationship students:
class Teacher extends Model
{
public function students()
{
return $this->hasMany(Student::class, 'teacher_id');
}
}
In your controller you can do the following:
public function example(){
$teachers = Teacher::where('teacher_status','active')->withCount('students')->get();
return view('teacherViewExample', compact('teachers'));
}
In your view (teacherViewExample):
<table>
<thead>
<tr>
<th>Teacher Name</th>
<th>Students Count</th>
</tr>
</thead>
<tbody>
#foreach($teachers as $teacher)
<tr>
<td>{{ $teacher->name }}</td>
<td>{{ $teacher->students_count }}</td>
</tr>
#endforeach
</tbody>
</table>
Full documentation on how to use withCount() here: https://laravel.com/docs/9.x/eloquent-relationships#counting-related-models
Sometimes you may want to count the number of related models for a
given relationship without actually loading the models. To accomplish
this, you may use the withCount method. The withCount method will
place a {relation}_count attribute on the resulting models:
If you want to count the number of students related to teacher without actually loading them you may use the withCount method and this add new propery named by a {relation}_count column on your resulting models. For example:
Teacher::where('teacher_status','active')->withCount('students')->get();
Also you need and to your Teacher model hasMany relation method to Students
In case frontend and backend are separated, i.e Laravel for backend, Angular for frontend, below are examples for Laravel:
In api.php,
Route::get('teacher-with-students-count', 'TeacherController#getTeacherWithStudentsCount');
In Teacher.php (model)
class Teacher extends Model
{
public function students()
{
return $this->hasMany(Student::class, 'teacher_id', 'id');
}
}
In TeacherController.php
public function getTeacherWithStudentsCount()
{
$teachers = Teacher::where('teacher_status','active')->withCount('students')->get();
return $this->giveSuccessResponse($teachers);
}

get access to collection laravel

I am a new learner of the laravel framework working on 3 models
customer,
accidents,
License
where the relations are as follows:
public function License()
{
return $this->hasOne(license::class,'driver_id');
}
public function cars()
{
return $this->hasMany(car::class);
}
In the controller I do like this:
public function AdminCustomers()
{
$customers = Customer::with('cars')->with('License')->get();
return view('admin.AdminCustomers',compact('customers'));
}
now I want to display all 3 models' data on view.blade page
<tbody>
#foreach($customers as $customer)
<tr>
<td>{{$customer->id}}</td>
<td>{{$customer->name}}</td>
<td>{{$customer->adderss}}</td>
<td>{{$customer->mobileNo}}</td>
<th>{{$customer->License->id}}</th>
<th>{{$customer->License->Exp}}</th>
<td>{{$customer->cars->id}}</td>
<td>{{$customer->cars->color}}</td>
<td>{{$customer->cars->model_no}}</td>
<td>{{$customer->cars->company}}</td>
</tr>
#endforeach
</tbody>
But it doesn't work and I didn't know where is the problem
the error Exception
Property [id] does not exist on this collection instance.
$customer->cars will return a collection as the relationship is hasMany so you need to loop over the collection in the view
#foreach($customers as $customer)
<tr>
<td>{{$customer->id}}</td>
<td>{{$customer->name}}</td>
<td>{{$customer->adderss}}</td>
<td>{{$customer->mobileNo}}</td>
<th>{{$customer->License->id}}</th>
<th>{{$customer->License->Exp}}</th>
#foreach($customer->cars as $car)
<td>{{$car->id}}</td>
<td>{{$car->color}}</td>
<td>{{$car->model_no}}</td>
<td>{{$car->company}}</td>
#endforeach
</tr>
#endforeach
check the name in the corrisponding table on db, and if its different from "id" specify it into the model, as
protected $primaryKey = 'xxx';

Laravel — Loop all data from multiple tables

Good day. I have researched about it, but nothings matched with my problem. Here's the scenario. I have courses table, and 3 more tables, assignments, quizzes, and reports. Now, what I want is, to get all of the records from the table assignments, quizzes, and reports and loop through all the records below a specific course.
Example Output: The order should be according to the first created item.
Course1
Assignment1
Quiz1
Quiz2
Assignment2
Report1
How can I do that with three different tables? I know how to use the basic many to many relationship, but for this. I really got stacked. Need help guys.
Note: I'm using Laravel5.1
Update1 — Course.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Course extends Model
{
protected $fillable = [];
public function assignments(){
return $this->belongsToMany('Assignment');
}
public function quizzes(){
return $this->belongsToMany('Quiz');
}
public function reports(){
return $this->belongsToMany('Report');
}
}
UPDATE2 as per request
<div class="table">
<table class="tabled">
<thead>
<tr>
<th>x</th>
</tr>
</thead>
<tbody>
#foreach($course_items as $course_item)
<tr>
<td>
{{ $table_name }} {{ $course_item->name }}
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
Based on the limited information available from your question, you will need to merge your relations into a single collection.
Using unions would be a better solution, if feasible, to improve efficiency, but hey-ho.
// Prepare not deleted scope
// I would suggest using Laravel's SoftDeletes, as it'll be better than writing your own implementation. But if not, you would be better to create this as a reusable scope on your model
$notDeletedScope = function ($query) {
return $query->where('deleted', 0);
};
// Find course with non-deleted relations
$course = Course::with([
'assignments' => $notDeletedScope,
'reports' => $notDeletedScope,
'quizzes' => $notDeletedScope,
])
->findOrFail($id);
// Combine relations into single collection
$merged = collect($course->assignments);
$merged = $merged->merge(collect($course->quizzes));
$merged = $merged->merge(collect($course->reports));
// Sort merged relations by created_at
$merged = $merged->sortBy('created_at');
#foreach ($merged as $relation)
#if ($relation->type === 'assignment')
// ...
#elseif ($relation->type === 'quiz')
// ...
#elseif ($relation->type === 'report')
// ...
#endif
#endforeach
Add to each model:
public function getTypeAttribute()
{
return snake_case(substr(strrchr(get_class($this), '\\'), 1));
}

Pagination in laravel 5 with realtion on where condition

Model smsHeader
protected $fillable = [
'type',
'imei',
'login',
'ver'
];
public function detail()
{
return $this->hasMany('App\Model\smsDetail', 'id_header');
}
Controller
$smsheader = smsHeader::orderBy('id', 'desc')->where('login', $user->email)->paginate(20);
return view('app.inbox')->with('smsheader', $smsheader);
Views
#foreach($smsheader as $header)
#foreach($header->detail->where('type', '1') as $detail)
<tr>
<td>{{$detail->number}}</td>
<td>{{$detail->name}}</td>
<td>{{$detail->text}}</td>
<td>{{$detail->date}}</td>
</tr>
#endforeach
#endforeach
but the result of pagination it was error, how i can set paginition in where smsdetail condition....??
sorry for my bad english
The error is showing for this line $header->detail->where('type', '1')
you can access $header->detail within foreach if you want to use where condition then you need to use get() at the end,like below
#foreach($smsheader as $header)
#foreach($header->detail->where('type', '1')->get() as $detail)
<tr>
<td>{{$detail->number}}</td>
<td>{{$detail->name}}</td>
<td>{{$detail->text}}</td>
<td>{{$detail->date}}</td>
</tr>
#endforeach
#endforeach
Laravel Queries within Blade views do not automatically execute. They simply prepare another QueryBuilder instance. You still need to run one of the "execute" methods (that will run PDOStatement::execute() underneath). These methods are:
first() (returns first result from result set as single object)
get() (which returns a Collection (ArrayObject with some added extra functionality))
paginate($numberPerPage) (which returns a Collection with extra meta information to pass to a $links property accessible via $collection->links())
In your example:
#foreach($smsheader as $header)
#foreach($header->detail->where('type', '1')->get() as $detail)
<tr>
<td>{{$detail->number}}</td>
<td>{{$detail->name}}</td>
<td>{{$detail->text}}</td>
<td>{{$detail->date}}</td>
</tr>
#endforeach
#endforeach

Trying to get property of non-object [laravel 5.2]

I'm getting trouble in getting the data from foreign key .
already make relation between 2 tables, but still error gave me this "Trying to get property of non-object"
this is my models
public function tourism()
{
return $this->belongsTo('App\Models\Tourism','tourism_id');
}
this is my controller
$ratings = Ratings::orderBy('rating','desc')->get();
$ratings = $ratings->take(6);
and this is my blade
<tbody>
#if($ratings)
#foreach($ratings as $data)
<tr>
<td class="center">{{$data->id}}</td>
<td class="center">{{$data->tourism_id->nama}}</td>
<td class="center">{{$data->rating}}</td>
</tr>
#endforeach
#endif
</tbody>
thanks
Try
<td class="center">{{$data->tourism->nama}}</td>
EDIT
This situation occurs when you trying get nama property.
But tourism_id it's just an integer, am I right?
First of all,for accessing related model you should use you relationship method(tourism) instead of FK field(tourism_id).
Then you should check are there any related model in tourims() or not. For this purpose i recommend you use ternary operator, so your line should be something like:
<td class="center">{{$data->tourism->first() ? $data->tourism->first()->nama : 'No tourism'}}</td>
Assuming you already have this controller and the model relationship as above:
function ratingsView() {
$ratings = Ratings::orderBy('rating','desc')->get();
$ratings = $ratings->take(6);
return View('rating')->with('ratings',$ratings);
}
In your views,
<tbody>
#if($ratings)
#foreach($ratings as $data)
<tr>
<td class="center">{{$data->id}}</td>
<td class="center">{{$data->tourism()->first()->nama}}</td>
<td class="center">{{$data->rating}}</td>
</tr>
#endforeach
#endif
</tbody>
Make sure your rating table have id, rating as well as tourism_id attributes and your tourism table have name attribute as well as of course there is data in both tables.
You definitely need to check the the availability of the data and handle it accordingly. But that is different issue
in your controller use it like this:
$ratings = Ratings::orderBy('rating','desc')->take(6)->get();

Resources