i have a case where i need to filter results by condition in 1-n relationship
so i have this 1-n relationship in User.php
public function permits()
{
return $this->hasMany('App\Permit');
}
result i want to retrieve is users where all permits are expired (expiry on permits table = 0), because 1 user can own many permits, and the condition i need to met is from all their permits they must be expired
my current query is like this, this pulled several hundred wrong data because i didn't understand yet how to implement where all permits expiry = 0
$users = User::where('club_id',$this->id)->whereHas('permits',function($q){
$q->where('expiry','<=','0');
})->get();
current solution which is bad solution (longer time to execute), just so you guys clearer with what i want to achieve
foreach($users as $key => $user){
foreach($user->permits as $permit){
if($permit->expiry > 0){
$users->forget($key); // unset from the users collection
break;
}
}
}
any help would appreciated thank you!
If you want users where all permits are expired
We can achieve this from whereDoesntHave() function.
$users = User::where('club_id',$this->id)
->whereDoesntHave('permits', function($query){
// query for not expired.
// I believe the column expiry value is 0 when premit is not expired.
$query->where('expiry', 0);
})
->get();
Technically what we did was get users where doesn't have non expired permits. Literally that means all permits are expired.
Related
I am having an issue while using order by based on multiple conditions.
User with most filled information should show up top and then the one's with less filled information.
$users = User::where('status',1)
->withCount('reviews')
->with('reviews','about')
->orderByRaw("CASE WHEN is_native != '0' AND photo != '' THEN 0 ELSE 1 END")// how i can match the about us relationship value here? means if user have added about intro then it should come first and reviews count?
->paginate(10);
Here is my About Relationship on User
public function about()
{
return $this->hasOne('App\UserAbout', 'user_id')->select('about');
}
NOTE: i am trying to do it with CASE, if there is any other good option you can please point out that.
Thank you
this means that you have to orderby about's count and then by review count, that will get the result you want:
$users = User::where('status',1)
->withCount(['reviews','about'])
->with('reviews','about')
->orderByRaw('about_count desc,reviews_count desc')
->paginate(10);
now user with 'about' will have about_count=1 others will have about_count =0
As #OMR suggested you can do that. But you don't need to use raw Query
$users = User::where('status',1)
->withCount(['reviews','about'])
->with('reviews','about')
->orderBy('about_count','desc')
->orderBy('reviews_count','desc')
->paginate(10);
I want to select all the users in my table "User" except the first One cause its the admin,
im using this function index in my controller but it doesn't work .
public function index()
{
// this '!=' for handling the 1 row
$user = User::where('id', '!=', auth()->id())->get();
return view('admin.payroll',compact('user'))->with(['employees' => User::all()]);
}
Better to used here whereNotIn Method
Note: first you find the admin role users and create a static array
$exceptThisUserIds = [1];
$user = User::whereNotIn('id', $exceptThisUserIds)->get();
It's not a good idea to specify the admin user with just id. A better design would be using some sort of a flag like is_admin as a property of your User model.
Still you can use the following code to get the users who have an id greater than 1:
User::where('id', '>', 1)->get()
For getting data skipping the first one you should use skip() method and follow the code like below
public function index()
{
$user = User::orderBy('id','asc')->skip(1)->get();
return view('admin.payroll',compact('user'))->with(['employees' => User::all()]);
}
Currently I have 3 tables
users
id, name
discount
id, name, active
discount_user
discount_id, user_id, start, end
I need to find all the active discounts for a current user which are currently running based on the start and the
end dates held on the pivot table.
I was hoping to be able to build a scopeActive method on the discount table to narrow down active discounts for the
current user, but I only want the date range to be added if I'm coming from the user table to find the discounts:
$discounts = User::find(1)->discounts()->active()->get(); // within date range
$active = Discount::active()->get(); // without date range check
On the user table I've extended the relations to have an 'activeDiscounts' relation which works using:
public function activeDiscounts() {
return $this->discounts()
->where('active', true)
->wherePivot('start', '>=', Carbon::now())
->wherePivot('end', '<=', Carbon::now());
}
Though this works, I don't think it's really best practice and would prefer to be able to use a scope on the discount.
Is there any way I can tell if I'm coming from the user table or through a pivot on the scope query? Also, if so, would I be
able to see the User ID so I can use it in the pivot query?
To answer on your question: You could use arguments in scope, e.g:
$discounts = User::find(1)->discounts()->active(true)->get(); // within date range
$active = Discount::active()->get();
Scope:
public function scopeActive($query, $withDates = false) {
return $query
->where('active', true)
->when($withDates, function($query){
$query
->wherePivot('start', '>=', Carbon::now())
->wherePivot('end', '<=', Carbon::now());
});
}
But I think that it is not better than your solution.
Also, you could use 2 different scopes.
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
...But if it's possible then I could Eloquent instead, but I do think with this problem i need to write a SQL-question.
I have a users table, and a points column. If I do want a top list then I just do order by points DESC (but with Eloquent and the user model).
To the question how do I do to found out which position any user has? Is it possible? Or should i make another table for toplist, please come with feedback and sorry for my poor english.
<?php
$toplist = User::orderBy('points', 'DESC')->get();
$me = Auth::user()->points;
$position = 1;
foreach($toplist as $user)
{
if ($user->id === $me)
{
break;
}
$position++;
}
dd($position);
how do I do to found out which position any user has? Is it possible?
You can get your current rank by count user who have more points than you and then plus one.
$me = Auth::user();
$rank = User::where('points', '>', $me->points)->count() + 1;