How do I get count from multiple columns - laravel - php

I want to fetch count requests by status for each request
I use this code and it works, but I don't think it's correct
'requests_count' => Request::where('user_id', auth()->id())
->addSelect([
'active' => Request::selectRaw('count(id)')
->where('status', 'active')
->where('user_id', auth()->id())
])
->addSelect([
'pause' => Request::selectRaw('count(id)')
->where('status', 'pause')
->where('user_id', auth()->id())
])
->addSelect([
'pending' => Request::selectRaw('count(id)')
->where('status', 'pending')
->where('user_id', auth()->id())
])
->addSelect([
'unapproved' => Request::selectRaw('count(id)')
->where('status', 'unapproved')
->where('user_id', auth()->id())
])
->first()
Is there a better and more effective way?

Related

Laravel - Hide a specific column [duplicate]

This question already has answers here:
Laravel - Method Illuminate\\Support\\Collection::makeHidden does not exist
(4 answers)
Closed 1 year ago.
I want to hide the columns password & OTP ,that is included in $users result. Actually these 2 columns are part of the users table. My ultimate need is that i need to join 3 tables : users,location,user_technical_details and want to hide the password & OTP columns in the users table. Can use any methods. Through any methods, i want to attain this result I've tried many methods. Nothing works. How to solve this? Any suggestions..
Things i tried:
1)
$users = DB::table('users')
->join('location', 'users.id', '=', 'location.id')
->join('user_technical_details', 'users.id', '=', 'user_technical_details.id')
->get();
$d=$users->makeHidden(['password','OTP']);
return response()->json([
'message' => 'profile viewed successfully',
'data' => $d,
'statusCode' => 200,
'status' => 'success'],200);
This generates the error - Method Illuminate\\Support\\Collection::makeHidden does not exist
2)
$users = DB::table('users')
->join('location', 'users.id', '=', 'location.id')
->join('user_technical_details', 'users.id', '=', 'user_technical_details.id')
->get();
$exclude_columns=['password','OTP'];
$get_columns = array_diff($users, $exclude_columns)->get();
return response()->json([
'message' => 'profile viewed successfully',
'data' => $get_columns,
'statusCode' => 200,
'status' => 'success'],200);
3)
$users = DB::table('users')
->join('location', 'users.id', '=', 'location.id')
->join('user_technical_details', 'users.id', '=', 'user_technical_details.id')
->get();
$d=collect($users->toArray())->except(['password','OTP']);
return response()->json([
'message' => 'profile viewed successfully',
'data' => $d,
'statusCode' => 200,
'status' => 'success'],200);
4)
protected $hidden = ['password','OTP'];
5)
$users = DB::table('users')->exclude(['password','OTP','ph_OTP','email_OTP','user_access_token','remember_token'])
->join('location', 'users.id', '=', 'location.id')
->join('user_technical_details', 'users.id', '=', 'user_technical_details.id')
->get();
return response()->json([
'message' => 'profile viewed successfully',
'data' => $users,
'statusCode' => 200,
'status' => 'success'],200);
This generates the Error -Call to undefined method Illuminate\\Database\\Query\\Builder::exclude()
when you want to limit the attributes, such as passwords, that are included in your model's array or JSON representation. To do so, add a $hidden property to your model. In attributes that are listed in the $hidden property's array will not be included in the serialized representation of your model:
class User extends Model
{
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = ['password','OTP'];
}
now in your code you have to use User model instead of DB facade:
$users = User::query()
->join('location', 'users.id', '=', 'location.id')
->join('user_technical_details', 'users.id', '=', 'user_technical_details.id')
->get();
now, $users will not have the hidden attributes

Laravel : How to get object in column with query builder

I want to display what kind of data I have described below, but I don't know the keywords.
For now, this is my data:
And this is the result I want:
This is, my controller:
$data = DB::table('tr_doctor_schedules as sch')
->select('sch.id as schedule_id','doctor_name','hospital_name','estimated_practice_time','day','from_time','until_time')
->join('mst_hospitals as hos', 'hos.id', '=', 'sch.hospital_id')
->join('mst_doctors as doc', 'doc.id', '=', 'sch.doctor_id')
->join('tr_doctor_schedule_details as dtl', 'dtl.doctor_schedule_id', '=', 'sch.id')
->where('sch.hospital_id', $hosId)
->where('sch.doctor_id', $docId)
->first();
if ($data) {
return response()->json([
'success' => true,
'message' =>'success',
'data' => $data
], 200);
} else {
return response()->json([
'success' => false,
'message' => 'Data not found.',
], 400);
}
Thanks
Try this
$data = DB::table('tr_doctor_schedules as sch')
->selectRaw('sch.id as schedule_id,doctor_name,hospital_name,estimated_practice_time,GROUP_CONCAT(day) as day,from_time,until_time')
->join('mst_hospitals as hos', 'hos.id', '=', 'sch.hospital_id')
->join('mst_doctors as doc', 'doc.id', '=', 'sch.doctor_id')
->join('tr_doctor_schedule_details as dtl', 'dtl.doctor_schedule_id', '=', 'sch.id')
->where('sch.hospital_id', $hosId)
->where('sch.doctor_id', $docId)
->groupBy('sch.id')
->first();

Decrement value in a loop

I am trying to make a query model where every time a query is posted, specific users are notified by mail and their records are decremented by 1.
Mail is working fine but the decrement is happening by the number of users identified and not 1.
Have tried various P&C.
$exclusive = DB::table('user_plans')
->leftJoin('companies', 'companies.id' , '=', 'user_plans.user_id')
->select('user_plans.*')
->where('user_plans.service_id' , '=', $input['project'])
->where('user_plans.lead_type' , '=', 2)
->where('user_plans.count' , '>', 0)
->limit(5)
->get();
$shared = DB::table('user_plans')
->leftJoin('companies', 'companies.id' , '=', 'user_plans.user_id')
->select('user_plans.*')
->where('user_plans.service_id' , '=', $input['project'])
->where('user_plans.lead_type' , '=', 1)
->where('user_plans.count' , '>', 0)
->limit(500)
->get();
$project = DB::table('services')
->select('services.*')
->where('services.id' , '=', $input['project'])
->get();
if (count($exclusive) > 0) {
foreach ($exclusive as $exclusive) {
Mail::send('emails.exclusive', array(
'name' => $input['name'],
'email' => $input['email'],
'phone' => $input['phone'],
'detail' => $input['detail'],
'project' => $project[0]->name,
'budget' => $input['budget']
), function($message) use ($exclusive) {
$message
->to($exclusive->lead_email)
->subject('CXO Forest Contact Us!');
});
//This part is not working
$deduct = DB::table('user_plans')
->where('user_plans.user_id' , '=', $exclusive->user_id)
->where('user_plans.count' , '>', 0)
->where('user_plans.type' , '=', 2)
//->get();
->decrement('count', 1);
}
} else {
if (count($shared) > 0) {
foreach ($shared as $shared) {
Mail::send('emails.exclusive', array(
'name' => $input['name'],
'email' => $input['email'],
'phone' => $input['phone'],
'detail' => $input['detail'],
'project' => $project[0]->name,
'budget' => $input['budget']
), function($message) use ($shared) {
$message
->to($shared->lead_email)
->subject('CXO Forest Contact Us!');
});
$deductx = DB::table('user_plans')
->where('user_plans.user_id' , '=', $shared->user_id)
->where('user_plans.count' , '>', 0)
->where('user_plans.type' , '=', 2)
->decrement('count', 1);
}
} else {
Mail::send('emails.exclusive', array(
'name' => $input['name'],
'email' => $input['email'],
'phone' => $input['phone'],
'detail' => $input['detail'],
'project' => $project[0]->name,
'budget' => $input['budget']
), function($message) use ($shared) {
$message
->to('amit.khare#studyspectrum.com')
->subject('Urgent: This lead does not have any takers');
});
}
}
Every time the code runs, deduct should reduce user_plans by 1 and not the number of emails sent.
Thanks guys for the help.
Here's the part part that is not working, try this:
DB::table('user_plans') ->where('user_plans.user_id' , '=', $exclusive->user_id) ->where('user_plans.count' , '>', 0) ->where('user_plans.type' , '=', 2) ->take(1)->delete();

How to use the same eloquent query twice, but with one different where clause?

I have this query:
User::leftJoin('friends', function ($join) {
$join->on('friends.user_id_1', '=', 'users.id')
->orOn('friends.user_id_2', '=', 'users.id');
})
->where(function ($query) use ($myID) {
// Group orwhere functions so the query builder knows these belong together
$query->where([
'friends.user_id_1' => $myID,
'friends.accepted' => true
])
->orWhere([
'friends.user_id_2' => $myID,
'friends.accepted' => true
]);
})
->where('users.id', '!=', $myID) // Exclude the user with id $myID
->get();
https://stackoverflow.com/a/41832867/5437864
I want to use this query twice, but with a different where clause. Is it possible to reuse this query without copying the whole code? And if so, how?
I used the PHP clone keyword. I'm not sure if this is the best solution, but it helps. Any other suggestions are welcome.
$friends_query = User::leftJoin('friends', function ($join) {
$join->on('friends.user_id_1', '=', 'users.id')
->orOn('friends.user_id_2', '=', 'users.id');
})
->where(function ($query) use ($myID) {
// Group orwhere functions so the query builder knows these belong together
$query->where([
'friends.user_id_1' => $myID,
'friends.accepted' => true
])
->orWhere([
'friends.user_id_2' => $myID,
'friends.accepted' => true
]);
});
$friends_me = clone $friends_query;
$friends_me = $friends_me->where('users.id', '!=', $myID);
$friends_others = clone $friends_query;
$friends_others = $friends_others->where('users.id', '=', $myID);
$query = User::leftJoin('friends', function ($join) {
$join->on('friends.user_id_1', '=', 'users.id')
->orOn('friends.user_id_2', '=', 'users.id');
})
->where(function ($query) use ($myID) {
// Group orwhere functions so the query builder knows these belong together
$query->where([
'friends.user_id_1' => $myID,
'friends.accepted' => true
])
->orWhere([
'friends.user_id_2' => $myID,
'friends.accepted' => true
]);
});
Adding extra where to existing query
$query->where('users.id', '!=', $myID)
$query->get();
Check this link for another example
Example

Laravel 4.2 - Eloquent WHERE clause with OR and reverse parameters

I have Eloquent statement in Laravel 4.2 that looks like this
$user_message_block = Message::where('responder_id', '=', Auth::user()->id)
->where('user_id', '=', $user->id)->first();
Then if $user_message_block doesn't exist I also have to check for a reverse case scenario and I do it like this...
if(!$user_message_block){
$user_message_block = Message::where('responder_id', '=', Auth::user()->id)
->where('user_id', '=', $user->id)->first();
}
What I really would like to do is run a single query that checks for both scenarios at once..
In pseudo expression I need something like this:
$user_message_block = Message::where('responder_id', '=', Auth::user()->id,
'AND', 'user_id', '=', $user->id,
'OR', 'responder_id', '=', $user->id,
'AND', 'user_id', '=', Auth::user()->id)->first();
So basically I need to
SELECT Message where (responder_id=x AND user_id=y) OR where (responder_id=y AND user_id=x)
How could I do this using Eloquent. I am unable to find more about OR and AND statements used with Eloquent.
Thanks!
UPDATE:
After more looking I found that this seems to work (still testing a lot)
$user_message_block =
Message::where(['responder_id' => Auth::user()->id, 'user_id' => $user->id])
->orWhere(['user_id' => Auth::user()->id, 'responder_id' => $user->id])
->first();
OR
$user_message_block =
Message::where(['responder_id' => Auth::user()->id, 'user_id' => $user->id])
->orWhere(['user_id' => Auth::user()->id, 'responder_id' => $user->id])
->get();
Are there any drawbacks to this that I need to consider?
It may be very complicated to do in Eloquent but this does exactly what you need using Laravel's query builder without reverting to raw SQL.
DB::table('messages')
->where(function($query)
{
$query->where('responder_id', '=', 'x')
->where('user_id', '=', 'y');
})
->orWhere(function($query) {
$query->where('responder_id', '=', 'y')
->where('user_id', '=', 'x');
})
->get();
This is what I get from running a toSql() on it:
select * from `messages` where (`responder_id` = ? and `user_id` = ?) or (`responder_id` = ? and `user_id` = ?)
Try this to see if it works with Eloquent.
Message::where(function($query) {
$query->where('responder_id', '=', 'x')
->where('user_id', '=', 'y');
})->orWhere(function($query) {
$query->where('responder_id', '=', 'y')
->where('user_id', '=', 'x');
})->get();
It should work.
I credited Noah for the solution on account of providing a working solution and the effort he made in helping me out. I did end up using a different solution however..
$user_message_block =
Message::where(['responder_id' => 'x', 'user_id' => 'y'])
->orWhere(['user_id' => 'x', 'responder_id' => 'y'])
->get();
In my speciffic case I only need the first record found so this works for me
$user_message_block =
Message::where(['responder_id' => 'x', 'user_id' => 'y'])
->orWhere(['user_id' => 'x', 'responder_id' => 'y'])
->first();
Suffice it to say,, I found a solution similar to mine in phpacademy videos by Alex. And I stumbled upon this too Laravel eloquent SQL query with OR and AND with where clause

Categories