Laravel get users by state using city id - laravel

I have users table where has city_id and each city in cities table has state_id. How I can get users using city_id from any state?
Here is my code:
$users = User::role('company')
->when((int) $state, function ($query, $state) {
// here query
})
->when((int) $city, function ($query, $city) {
return $query->where('city_id', $city);
})
->get();
I tried:
$users = User::role('company')
->when((int) $state, function ($query, $state) {
$cities = City::where('state_id', $state)
->pluck('id')
->toArray();
return $query->whereIn('city_id', $cities);
})
->when((int) $city, function ($query, $city) {
return $query->where('city_id', $city);
})
->get();
It's work but how to do this query correctly without make new query with City model?

have you built the relation between user and city? it should be something like:
public function city()
{
return $this->belongsTo(City::class, 'city_id');
}
you can use that relation to get users where has a city that belongs to that state:
$users = User::role('company')
->when((int) $state, function ($query)use ($state) {
return $query->whereHas('city',function ($query)use ($state){
$query->where('state_id',$state);
});
})
->when((int) $city, function ($query)use($city) {
return $query->where('city_id', $city);
})
->get();

You can use Laravel HasManyThough
given that you have a state, each state has many cities, each city has many users
then in the state model, you can add this function
public function users()
{
return $this->hasManyThrough(User::class, City::class);
}
this function will return all the users in a given state
example:
$state = State::first();
$users = $state->users;
for further info read the docs

Related

Laravel How to get `->sum('count')` in `whereHas` subquery?

I have 3 model Transaction , Cart , Acceptedcart.
in Cart model I have transaction_id and in Acceptedcart model have cart_id.
in Transaction.php my relationship to carts:
public function carts()
{
return $this->hasMany(Cart::class);
}
in Cart.php my relationship to accepted carts :
public function accepted_carts()
{
return $this->hasMany(Acceptedcart::class);
}
And the query to get the transactions where acceptedcart->sended== false:
$transactions = Transaction::whereHas('carts.accepted_carts', function ($query) {
$query->where('sended', false);
})->get();
Now I want to get sum() of count column in acceptedcart, where I can set the sum()?
$transactions = Transaction::whereHas('carts.accepted_carts', function ($query) {
$query->where('sended', false);
})->sum('count);
Or
$transactions = Transaction::whereHas('carts.accepted_carts', function ($query) {
$query->where('sended', false)->sum('count');
})->get();
is there Only one way that foreach on the ->get() result ?
Try this
Transaction.php
public function accepted_carts()
{
return $this->hasManyThrough(Acceptedcart::class, Cart::class);
}
Query
$transactions = Transaction::query()
->whereHas('accepted_carts', fn ($query) => $query->where('sended', false))
->withCount([
'accepted_carts' => fn ($query) => $query->select(DB::raw('SUM(count) as accepted_carts_sum'))
])
->get();

Laravel Using nested with

I couldn't do what I wanted to do with Laravel, actually what I want to do is as follows,
I send getTruck id and list truckHistory with witdh, and I want to pull trukInvoice information with truckHistory invoice_id. But i am getting error where am i doing wrong?
Mysql Connection is as follows.
http://localhost:3000/truck/1
"trucks" table column "plate"
"invoice_details" column "plate_no"
"invoice_details" column "invoice_id"
"invoice" column "id"
Truck Controller
public function getTruck($id)
{
$truck = Truck::find($id)->with([
'truckHistory' => function($query){
// return $query->with(['trukInvoice']);
}
])->first();
return $truck;
}
Truck Model
public function companys()
{
return $this->belongsTo(Contact::class, 'company_id', 'id');
}
public function getCompanyNameAttribute()
{
return $this->companys()->first()->name;
}
public function truckHistory(){
return $this->hasMany(InvoiceDetail::class,'plate_no','plate');
}
public function trukInvoice(){
return $this->belongsTo(Invoice::class,'invoice_id','id');
}
Try this:
$truck = Truck::leftJoin('invoices', 'trucks.invoice_id', 'invoices.id')
->leftJoin('invoice_details', 'trucks.plate_no', 'invoice_details.plate')
->select('*')
->first();
or
$truck = Truck::with(['invoices' => function ($query) {
$query->whereHas('invoice_details', function ($q){
$q->whereNotNull('invoice_details.plate');
});
}])->first();
Check the documentation on restraining eager loads.

how to select specific fields from the tables in laravel

This works but it gives all the fields of account table but only few are required.
$data = Loan::select('*')
->with([
'member' => function ($query) {
$query->addSelect('id', 'name');
},
'member.account'
])
->get();
This gives account: null
$data = Loan::select('*')
->with([
'member' => function ($query) {
$query->addSelect('id', 'name');
},
'member.account'=> function ($query) {
$query->addSelect('id', 'account'); // if this line is commented, all the fields are returned but I just need few fields.
}
])
->get();
Member model:
public function account()
{
return $this->hasOne(Account::class);
}
Account model:
public function member()
{
return $this->belongsTo(Member::class);
}
How can I get only the required fields of account table?
You can define the relationship and set it to give you specific columns like this.
on Member model
public function account()
{
return $this->hasOne(Account::class)->select(['id', 'account']);
}
You can try to define required fields in with:
$data = Loan::select('*')
->with([
'member' => function ($query) {
$query->addSelect('id', 'name');
},
'member.account:id,number'
])
->get();
Your are close you just need to select the foreign key column that points to your account model , I guess it would be account_id, So you basically need to select 3 columns from your table which are select(['id', 'name','account_id'])
$data = Loan::with(['member' => function ($query) {
$query->select(['id', 'name','account_id'])
->with(['account'=> function($query){
$query->select(['id','name']);
}]);
}])
->get();
So if you have another nested relation account -> type and you need specific columns from type so you need to select the foreign key column from accounts models as
with(['account'=> function($query){
$query->select(['id','name','type_id'])
->with(['type'=> function($query){
$query->select(['id','name']);
}]);
}]);

Laravel whereHas Filter sub relation

Is that any method to filter the employees and the manpower table record does not return also?
$result = Pwra::with('purchaseOrder', 'manpower')
->where('pwra_dt', $date)
->where('time_session', $session)
->whereHas('manpower.employees', function ($q) {
$q->where('status', 1);
})
->get();
Pwra Class
public function manpower()
{
return $this->hasMany('App\Models\Manpower', 'pwra_uuid', 'pwra_uuid');
}
Manpower Class
public function employee()
{
return $this->hasOne('App\Models\Employees', 'employees_uuid', 'employees_uuid')->where('status', 1);
}
What I expected is: When the employees Status = 0, it will not return any record even manpower.
you can try 2 level whereHas()
$result = Pwra::with('purchaseOrder', 'manpower')
->where('pwra_dt', $date)
->where('time_session', $session)
->whereHas('manpower', function ($q) {
$q->whereHas('employees',function($subQ){
$subQ->where('status', 1);
});
})
->get();
whereHas('manpower.employees' it will not work

How to get posts of followed users

I'm trying to make news feed page, but in this page I need to output articles ordered by date and also they must belong to the user, which authed user follows. I tried a few things and than realised that I have the wrong logic. So in user model I have:
function followers()
{
return $this->belongsToMany('App\User', 'followers', 'user_id', 'follower_id');
}
function follows()
{
return $this->belongsToMany('App\User', 'followers', 'follower_id', 'user_id');
}
function articles(){
return $this->hasMany('App\Article');
}
and than in article I have the relationships:
public function user()
{
return $this->belongsTo('App\User');
}
I don't know if I can simplly get all articles and than output the ones the user follows. I'm kind of confused.
here is the code I use in controller:
$followinguserarticle = Article::whereHas('user.follows', function($q) {
$q->where('id', auth()->id());
})
->latest()
->get();
And than I try to loop through them with:
#foreach($followinguserarticle as $followinguserarticles)
<a>followinguserarticles->title</a>
#endforeach
Use the whereHas():
Article::whereHas('user.followers', function($q) {
$q->where('id', auth()->id());
})
->latest()
->get();
You can eager load relationship on authed user instance
$authed = Auth::user();
$authed ->load('follows.articles');
Now you have articles of users whom users follows
foreach($authed->follows as $follow){
foreach($follow->articles as $article){
//Now you have access to each article
}
}
So the solution I found is like this:
//get list of follower ids
$follows = Auth::user()->follows->pluck('id');
//get articles of those that user follows
$articles = Article::whereIn('user_id',$follows)
->with('user')
->latest()
->limit(10)
->get();

Resources