Laravel Getting only certrain data from pivot table - php

I'm using Laravel to query users that have a score ( row in eventscore table )
And i want to return all the users that have scores for the event with an ID of 3
Is it possible to only return the score of every user, found in the pivot table ( see results below )
This is the code i'm using
$persons = Person::whereHas('eventscore', function($q) {
$q->where('id', 3);
})->with('eventscore')->get();
return $persons;
Thank you!

Try this:
// Person model
// accessor for easy fetching the score from the pivot model
public function getScoreAttribute()
{
return ($this->pivot && $this->pivot->score)
? $this->pivot->score
: null;
}
// example usage for the event's page (I assume participants is the relation)
$event = Event::with('participants')->find(3);
// somewhere in the view template
#foreach ($event->participants as $participant)
{{ $participant->name }} - score: {{ $participant->score }}
#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);
}

Efficient way to handle date between Controller and view in laravel

I have an app that reads through a table of data and based on the name of the person, does a for each loop, producing a card for each job that is assigned to that user.
EG.
user1 Job 1
user1 Job 2
user2 Job 3
user3 Job 4
... could be 3000 plus records here with up to 40/50 users
The controller collects the data from the table and sends it in bulk to the view for a foreach user statment to produce the code for each user then for each Job where it matches the user.
Controller code:
function dash()
{
if($user = Auth::user())
{
$users= User::all();
$jobs= Job::all();
return view('jobview', compact('users','jobs'));
}
if(Auth::guest())
{
return redirect('/home');
}
}
The view code is simple:
#foreach($users as $user)
#foreach($jobs as $job)
#if ($job->technician == $user->id)
<!--The code in this include generates a few lines of code to create the card-->
#include('layouts/sublayouts.jobscard')
#endif
#endforeach
#endforeach
The core problem is, there can be over 3000 cards (all need to be visable at the same time) and there can be 40 users to show.
I assume the slowness is the for each loop being done in the view?
Any guidance would be appriciated.
Thanks
Matt
Try something like, this will do the comparasion when getting the data from the database instead, should be alot faster:
$user_id = Auth::user() -> id;
$jobs = Job::Where('technician', '=', $user_id)->get();
return view('jobview', compact('jobs'));
EDIT:
In response to comment for all Jobs, do an inverse One-to-many relationship, for example:
//Job Model
class Job extends Model
{
public function technician()
{
return $this->belongTo('App\User');
}
}
//Controller
$jobs= App\Job::All();
return('jobview', compact('jobs')
//View
#foreach($jobs as $job)
{{ $job -> technician -> [Insert Some User property you want here] }}
{{ $job -> jobName }}
And if you want to "group" them by user simply do orderBy('technician') in your controller.
Take a closer read here

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.

Laravel - Get users for tickers

I understand this might be really simple but I cannot get my head around it.
Say I am fetching all tickets
$tickets = Ticket::all();
And with a single line, I want to fetch all the users associated with each ticker, (every ticket has a field with user_id), is there a single line of code, which can do it in Laravel. I can do the old way to loop though each ticket and fecth the details for each user as below, but am just looking for best practices here.
foreach($tickets as $ticket):
$ticket->user = User::find($ticket->user_id);
endforeach;
i'm assuming you have defined a correct relationship in your models.
You can use eloquent relationship of laravel to get all tickets of users
$tickets = User::with('tickets')->get();
to get data if user has at least one ticket you can use the below code
$tickets = User::has('tickets')->get();
To get all tickets only:
$tickets = Ticket::all();
and then in your blade you can do:
#foreach($tickets as $ticket)
// getting user using relationship
{{ $ticket->user->name }}
#endforeach
or to get tickets associated with user you can use
$tickets = Ticket::whereHas('user', function ($q) {
$q->with('user');
})
->get();
to know more about relationships visit this
The first, you declare relation model Ticket with model User:
This is code in model Ticket:
public function user()
{
return $this->hasOne('App\Model\User', 'user_id', 'id'); //id is the primary key in User table
}
then fetching all tickets with user info
$tickets = Ticket::load('user')->all();
or
$tickets = Ticket::with('user')->all();
If you want to get the list of all tickets where has user, with the user associated with each ticket, try this:
$tickets = Ticket::whereHas('user', function ($query) {
$query->with('user');
})
->get();
If you are sure that all tickets have an associated user, use this:
$tickets = Ticket::with('user')->get();

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

Categories