Sort the data linked by a relationship by date - laravel

I'm having a problem sorting projects based on the date of the last task associated with it. I explain better.
I have a relationship between project and tasks One to Many (as a project can have one or more tasks). In the project table, for each project, I have a column where I print the date of the last task done, as you can see in the blade view shown below. So far everything ok.
Now the projects are sorted by default in ascending order of creation of each project (so the last project shown in the table is the one that is added last).
What I want is to sort the projects by the date obtained from the last task associated with that project through the column corresponding to the date of the last task I get as shown below.
Model Project:
class Project extends Model
{
use HasFactory;
protected $fillable = [
'title',
'name',
];
public function tasks()
{
return $this->hasMany(Task::class);
}
}
Controller:
public function index()
{
$projects = Project::withCount('tasks')->get();
return view('project.index', compact('projects'));
}
View:
<table id="tabledata">
<thead>
<tr>
<th></th>
<th>Title</th>
<th>Name</th>
<th>Date last task</th>
<th>N. Tasks</th>
</tr>
</thead>
<tbody>
#foreach ($projects as $project)
<tr>
<td></td>
<td class="p-4">{{ $project->title}}</a></td>
<td class="p-4">{{ $project->name }}</a></td>
<td class="p-4">{{ $project->tasks()->latest()->first()->created_at->format('d/m/Y') }}</td>
<td class="text-center">{{ $project->tasks_count}}</td>
</tr>
#endforeach
</tbody>
</table>

To sort your query by the data of relationship column, you can change your query to something like this:
$projects = Project::with('tasks')->orderByDesc(Task::select('created_at')->whereColumn('tasks.project_id', 'project.id')->latest()->take(1))->withCount('tasks')->get();
orderBy() and orderByDesc() query builder methods support passing a query, instead of just a column name.
What we did here is:
We took the tasks of the project
We passed in a query as a subquery to the orderByDesc query builder method.
Inside the subquery:
We selected the created_at column from the tasks table.
We limited the results by comparing the project_id column of tasks table to the id column of the projects table.
Then we call the latest() method, which sorts the tasks to the recent record first.
And lastly, we limit the results to only one row, since a subquery can only return a single row and column
You can read more about how it works with different types of relationships here

Related

Fetching a string of IDS in a Column using explode (Eloquent model Laravel)

For the table Exam I have this:
--id----section_id
--1----- 2,3
when I use this in Exam.php Model:
public function Sections(){
return $this->belongsTo(Section::class, 'section_id');
}
It only shows and take in consideration the section_id=2 but not both of the IDS.
How I can get Info from both Ids ?
in the blade.php :
#foreach ($Exams as $exams)
<tr>
<td>{{$exams->id}}</td>
<td>{{$exams->Sections}}</td>
</tr>
#endforeach

Trying to get property 'department' of non-object in laravel with one to many relationship

Actually I want to relationship with two tables one is the student table where some data of a student. another table has department notice. I want to access the department notice according to the student department. The student has login id, password, dept & much other information of an individual student on the student table. The screenshot is given below
Now I want to try to access according to the dept. Another Table dept. the screenshot is given below.
Here given the CseDepartment model
public function administration()
{
return $this->belongsTo('App\Administration','dept');
}
Administration model
public function department()
{
return $this->hasMany('App\CseDepartment','dept');
}
function is given below
public function individualdepartment(){
$this->AdminAuthCheck();
$id=Session::get('id');
$student=Administration::find($id);
return view('Student.department',compact('student'));
}
view page department
#foreach ($student as $students)
{{-- expr --}}
<tr>
<td>{{$students->department->name}}</td>
<td>{{$students->department->message}}</td>
<td></td>
<td></td>
<td></td>
</tr>
#endforeach
In your controller, you are calling the find() method, which gives you one object, a student.
$student=Administration::find($id);
In your blade page, you are then asking to loop on that single object and produce a collection:
#foreach ($student as $students) // There is only ONE student, this will not loop.
If you want the above to work, you can grab a collection from your controller:
// Note the plural naming convention to make it a little more clear
$students=Administration::all();
return view('Student.department',compact('students'));
Then in your blade file, you can loop like this:
#foreach ($students as $student) // note the name plural --> singluar
<tr>
<td>{{$student->department->name}}</td> // Now you have a single student
<td>{{$student->department->message}}</td>
This will resolve the non-object error.

Property [name] does not exist on this collection instance. Eloquent 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

repeat laravel query result 4 times

i have a question on how to accomplish this task..
how can i repeat the result of a query 4 times and then add a name from other database.. please check this attach image.
i have a database for flight number. and a database for employee name.
this is my code so far
#foreach ( $daily_flight as $d_f)
{{ $d_f->flight_num}}
#endforeach
<table>
#foreach ($csa as $emp)
<tr>
<td>{{ $emp->name }}</td>
</tr>
#endforeach
</table>
Let's imagine that you have 2 tables: flights and employees. Let us also imagine that the flights Table has columns like id, flight_num, etc. Simultaneously; we would also assume that the employees Table contain fields like: id, flight_id, name, etc. Now, working under this arbitrary condition, one can simply write a Query that joins the 2 tables provided there is any kind of JoinCondition that can be established between the 2 - for example: ON employees.flight_id=flights.id.
This would be how to do this from the Controller:
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use App\User;
use App\Flights; //<== JUST SOME ARBITRARY IMPORTS... MODIFY TO SUIT YOU
use App\Employees; //<== JUST SOME ARBITRARY IMPORTS... MODIFY TO SUIT YOU
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\URL;
class FlightsController extends Controller {
public function flightSchedule(){ //<== ANOTHER ARBITRARY ACTION METHOD
// ASSUME FOR AN INSTANT THAT YOU HAVE 2 TABLES:
// 1.) flights
// 2.) employees
// YOU COULD USE THE join CLAUSE TO JOIN THE 2 TABLES TOGETHER
$flightData = DB::table('flights')
->join('employees', 'employees.flight_id', '=', 'flights.id')
->select('flights.*', 'employee.*')
->groupBy('employees.name')
->get();
// THEN ONCE YOU HAVE YOUR RESULT, IT WOULD BE ONLY
// A MATTER OF LOOPING THROUGH THE RESULT-SET IN THE VIEW SCRIPT
// AND STRUCTURING YOUR MARK-UP AS YOU SEE FIT LIKE THIS:
return view("flights.schedule", array("flightData"=>$flightData));
}
}
Now, in your View Script in our Arbitrary Example; flights/schedule.blade.php
<!-- FICTITIOUS FILE-NAME=> flights/schedule.blade.php -->
<table>
<tr>
<th>FLIGHT NUMBER</th>
<th>ASSIGNED EMPLOYEE</th>
</tr>
<tbody>
#foreach($flightData as $data)
<tr>
<td>{{ $data->flight_num }}</td>
<td>{{ $data->name }}</td>
</tr>
#endforeach;
</tbody>
</table>

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