Laravel Dashboard Query on Enrolled students this Year? - php

For example, I have five tables (School, Student, Class, Session, and Enrollment) the Enrollment Table store the Primary Key of other tables, Now I like to count in Session wise that how Many students have enrolled in Session 2019-2020 and display in the dashboard.
public function index()
{
$schools=School::all();
$students=Student::all();
$sessions=Session::all();
$enrollements=Enrollement::all();
return view('dashboard',compact('schools','students','enrollements','sessions'));
}
when I write {{$sessions->latest()}} it show the following error """Method Illuminate\Database\Eloquent\Collection::latest does not exist""
and how to pass session year (String) to enrollement to count?
could anyone suggest the best method to solve the following problem?

For collections , use last() method ($sessions->last()) https://laravel.com/docs/7.x/collections#method-last
I don't know how your table is structured, but you need to group by year and then compare
$enrollementsByYear = Enrollment::selectRaw('year, count(year) AS enrollmentsByYear')
->groupBy('year')
->get();
Then in $enrollementsByYear you will have a collection where you can compare the year of the session and mount your table. Change year with the actual column name.
You can easily compare with something like:
#foreach ($sessions as $session)
#foreach ($enrollementsByYear as $y)
#if ($session->year == $y->year)
<label>{{ $session->year }}</label>: <span> {{$y->enrollmentsByYear }}</span>
#endif
#endforeach
#endforeach

Related

How to display the most recent single record in laravel using eloquent

How can i display the most recent single record in laravel using eloquent the solution i have shown below only shows the oldest record in the database not the most recent.
I have two tables a payments table and tenants table.
payments table has the following columns
id
amount
rent_from
rent_to
Payments table has a many to one relationship with the tenants table.
In my index page i wish to only display the latest payment per tenant (tenant_id)
In my controller i have
public function index() {
$payments = Payment::groupBy('tenant_id')->get();
return view('payments.index')->with('payments',$payments);
}
index.blade.php
#foreach ($payments as $post)
{{ $post->id }}
{{ $post->amount }}
{{ $post->rent_from }}
{{ $post->rent_to }}
{{ $post->tenant['name'] }}
#endforeach
This show the oldest record not the latest. How can i display the most recent payment record for each tenant - only one most recent payment record per tenant_id
you could make a new relation called 'lastPayment' by using 'hasOne' with orderByDesc to get the last payment ....
class Tenant extends Model
{
public function lastPayment()
{
return $this->hasOne(Payment::class,'tenant_id')->orderByDesc('payments.id');
}
}
public function index()
{
$tenants= Tenant ::with('lastPayment')->get();
return view('payments.index')->with('tenants',$tenants);
}
The following gives me the output i needed. Is there a more eloquent way of expressing this function.
{
$payments = Payment::whereRaw('id IN (select MAX(id) FROM payments GROUP BY tenant_id)')->get();
return view('payments.index')->with('payments',$payments);}
latest() is a function that will order by with the column you provide in descending order.
public function index()
{
$payments = Payment::groupBy('tenant_id')->get()->latest('id');
return view('payments.index')->with('payments',$payments);
}

Laravel - Get additional column value from pivot table

I have Stores and Medicines tables with many to many relationship. Storing and updating work fine with attach and sync. The table structure is like below. I want to retrieve value of extra column (expired).
store_id | medicine_id | expired
1 2 1
1 3 0
Also I need to count total medicines which expired like this
Both models have withPivot('expired') model relation.
Controller
public function show($id)
{
$medicine = Medicine::findOrFail($id);
$stores = $medicine->findorfail($id)->stores()->get();
return view ('medicines', compact('medicine', 'stores'));
}
View
I can list medicines with this
#foreach ($stores as $store)
{{ $store->value('name') }}
{!! $store->pivot->expired == 1 ?
'Expired' : 'Not-Expired' !!}
View
#endforeach
I tried to count Cities like this:
#foreach($stores as $store)
{{ ($store->pivot->expired==1) }}
#endforeach
It gives 1 1. How can I count total cities with have expired Cetamols?
The following should work:
Sum on the relationship collection:
$stores->sum('pivot.expired');
Sum on the Query Builder:
Medicine::findOrFail($id)->stores()->sum('expired');
Also your controller code does not make much sense at the moment and could be simplified to this:
public function show($id)
{
$medicine = Medicine::findOrFail($id);
$stores = $medicine->stores;
return view('medicines', compact('medicine', 'stores'));
}
I removed the second call to findOrFail() and removed the get() since it is unnecessary.

Build database query in Laravel with eloquent or DB

I need your help to build a query in Laravel either eloquent or DB query would do too.
My table name is Users
To see the DB structure, open the following link:
https://jsfiddle.net/vardaam/mvqzpb2j/
Every user row has 2 columns referral_code and referred_by_code which means every user can refer to someone and earn bonus similarly the same user was also been referred by some one.
I would like to return the information on page with loop in users details along with Username of the user who had referred him to this. To track the same I created those 2 columns in the same table i.e.: referral_code and referred_by_code.
I do not know how to write this in 1 query or how to combine 2 queries and get the desired results.
My controller code looks like below:
$obj_users = User::get();
$codes = [];
$referrers = [];
foreach( $obj_users as $referred_by_code )
{
//Following fetches all user's referred_by_code's code
$codes[] = $referred_by_code->referred_by_code;
}
foreach ($codes as $code)
{
//Following fetches usernames of the given referred_by_code's codes
$referrers[] = User::where('referral_code', $code)->first()->username;
}
return view('users.users', compact(['users', 'paginate', 'referrers']));
The returning $users variable provides me loop of users data but I do not know how to attach those referrer's username to that object.
I tried my level best to describe, please ask incase what I said doesn't make sense, will be happy to provide further clarification.
Best
You can add into your User model the following relationship:
public function referredBy()
{
return $this->belongsTo(User::class, 'referred_code', 'referral_code');
}
In your controller you can use:
$users = User::with('referredBy')->get();
return view('users.users', compact('users'));
and later in your view you can use:
#foreach ($users as $user)
{{ $user->username }} referred by {{ $user->referredBy ? $user->referredBy->username : '-' }}
#endforeach

Correct way to run a select query from blades in laravel 5 using eloquent

What is the Correct Way to retrieve a column value based on certain select filter on a Model variable availed by compact method inside the blade. (Larevl 5)
I read that Its a bad practice to query database staright from views, and hence i followed the convention to avail the required data with compact method to view
However, In a scenario where I need to query another table based on certain column value returned in foreach loop inside a blade from first table, I am unable to figure out correct Approach
Example: I have two Models User & Group
Schema User Table
id,name,email,group_id
Scheme Group Table
id,groupname
Here is the UserController -> compact method
$users = \App\User::all(array('id','name','email','group_id'));
$groups = \App\Group::all(array('id','group_name'));
return view('user.index', compact('users','groups'));
Here how the blade needs them
#foreach ($users as $user)
<tr>
<th>{{$user->id}}</th>
<th>{{$user->name}}</th>
<th>{{$user->email}}</th>
<th>
<!-- Here i need to run something like
select group_name from group where id = $user->id -->
{{$groups->where('id','=',$user->group_id) }}
</th>
<th>Actions</th>
</tr>
#endforeach
I know this returns an array , and I'have two questions here
How to get the value for group_name column from the Group Model based on group.id = $user->id in a foreach loop
Since Its a bad practice to query db from blade, how would I avail the values from a model by passing data via compact from controller to blade, when the where clause parameter's are not yet known.
Edit 1:
I modified the last group query as
<th>#if($groups->where('id','=',$user->group_id))
#foreach($groups as $group)
{{$group->group_name}}
#endforeach
#endif
</th>
And I was able to get the result, however this again isn't a correct approach , so question remain unanswered
In User model
public function group()
{
return $this->belongsTo('App\Group');
}
In Group model
public function users()
{
return $this->hasMany('App\User');
}
In your controller
$users = \App\User::with('group')->get();
return view('user.index', compact('users'));
Now in your view you can do
$user->group->name;
I appreciate the fact that you know "It's bad practice to query from view".
Why don't you use join.
DB::table('users')->join('groups', 'users.group_id', '=', 'groups.id')->get();
Then pass the result to your view and loop through it.
Here you will have each user data associated with his group data.

Displaying a checkbox only for the shows(in the tvshow table) that don't match the entries for a given user id in the watchedtvshow table - Laravel

This is what I want to do:
Display a checkbox for the tvshow field entry(from the tvshow table) only if that field entry doesn't match the entries for a given user id in the 'watchedtvshow' table
Table structure for 'tvshow':
id tvshow
Table structure for 'watchedtvshow'
id uid tvid(id of the tvshow)
Here is my controller method:
$tvshow = TVShow::with('watchedtvshow')->get();
return View::make('browse',['tvshow' => $tvshow]);
My View:
#foreach($tvshow as $show)
{{ $show->title }} {{ 'a checkbox' }}
#endforeach
What I tried:
In my controller method:
$tvshow = TVShow::with('watchedtvshow')->get();
$uid = NULL;
if(Auth::check())
$uid = Auth::user()->id;
return View::make('browse',[
'tvshow' => $tvshow,
'uid' => $uid,
]);
In my view:
#foreach($tvshow as $show)
{{ $show->title }}
#foreach($show->watchedtvshow as $watchedtvshow)
#if($watchedtvshow->uid == $uid)
{{'don't show checkbox'}}
#else
{{'show checkbox'}}
#endif
#endforeach
#endforeach
The problem:
The thing is the second foreach loop executes only for the times it finds a watched tv show, otherwise it doesn't. So it just won't show any checkboxes.
I'm not an experienced coder, haven't really encountered anything like this before, I've spent three whole days trying to solve this, using count, for loops and what not, but I can't. Does anybody know how to achieve this?
First off a quick pointer: you can get the logged-in user's ID with Auth::id() rather than having to set it to null, then check if they're logged in then get the id directly off the model.
As for your problem, you're quite right that using the code you have you won't be getting the full story. What you need to do is get a list of all TV shows (regardless of user having it) and additionally a list of all TV shows the user has seen. Now, you can do this many ways, but the best 'Laravel way' is to model the relationship between User and TVShow. Your code doesn't mention this so I won't assume you have already done it. Your database is, of course, already set up for this so all you need to do is create the relationship. In this case, the relationship you need is a belongsToMany (a user can 'have' (have watched) many shows, and a show can 'have' (have been watched by) many users:
// in User.php
public function shows()
{
return $this->belongsToMany('TVShow', 'watchedtvshow', 'uid', 'tvid');
}
// in TVShow.php
public function users()
{
return $this->belongsToMany('User', 'watchedtvshow', 'tvid', 'uid');
}
Once you have this you can get a list of all users that have watched a show with:
$show->users;
Or you can get a list of all shows a user has watched with:
$user->shows;
Now putting that all together you should use Laravel's collections to detect whether a given item if in both arrays:
// in the controller:
$shows = TVShow::all();
if (Auth::check()) {
$watched = Auth::user()->shows;
} else {
// just create an empty collection so we can assume a consistent API
$watched = new \Illuminate\Support\Collection;
}
return View::make('browse', compact('shows', 'watched'));
// in browse.blade.php
#foreach($shows as $show)
{{ $show->title }}
#if ($watched->contains($show)
<span class="glyphicon glyphicon-ok"></span>
#else
<span class="glyphicon glyphicon-remove"></span>
#endif
#endforeach
Something like that?

Categories