Laravel: how to handle count in query - laravel

Currently I'm getting the list of table list in controller. And i got it successfully..But there is a problem, i return a list and a total.But when there is value package my count() is limited by skip - take .So I have to split it into 2 queries. Is there any way to combine those 2 queries into one to compact the code. Please give me your opinion. Thanks.
public function listData(Request $request)
{
$package = $request->package;
$userId = [1,3];
$list = List::whereIn('user_id', $userId)
->when(!empty($package), function ($query) use ($package) {
$query->where('idPackage', '=' . $package);
})->orderBy('created_at', 'DESC')->skip(0)->take(20)->get()->toArray();
$count = List::whereIn('user_id', $userId)
->when(!empty($package), function ($query) use ($package) {
$query->where('idPackage', '=' . $package);
})->count();
return response()->json([
'list' => $list,
'total' => $count
], 200);
}

This is so simple.. I think you should try this:
public function listData(Request $request)
{
$package = $request->package;
$userId = [1,3];
$list = List::whereIn('user_id', $userId)
->when(!empty($package), function ($query) use ($package) {
$query->where('idPackage', '=' . $package);
});
$count = $list->count();
$listData = $list->orderBy('created_at', 'DESC')->skip(0)->take(20)->get()->toArray();
return response()->json([
'list' => $listData,
'total' => $count
], 200);
}
good luck :))

Related

How to fetch data from the database in 2 different tables in Laravel Controller?

I don't know how to add $countries to the State queryString below. Could you help me
public function index(){
// $countries = Country::all();
$perPage = Requests::input('perPage') ?: 5;
return Inertia::render('State/Index',[
'states' => State::query()
->when(Requests::input('search'), function($query, $search){
$query->where('name', 'like', "%{$search}%");
})
->paginate($perPage)
->withQueryString(),
'filters' => Requests::only(['search', 'perPage']),
]);
}
You are missing $search variable.
And ->when($condition, function ...) need a true/false condition.
public function index(Request $request){
// $countries = Country::all();
// probably best to add validation at this point
$validated = $request->validate($rules);
$perPage = $request->input('perPage', 5); // set 5 as default when empty
$search = $request->input('search');
return Inertia::render('State/Index',[
'states' => State::query()
->when(!empty($search), function($query, $search){
$query->where('name', 'like', "%{$search}%");
})
->paginate($perPage)
->withQueryString(),
'filters' => $request->only(['search', 'perPage']),
]);
}

How to use regex or any other operator with whereIn clause

Is there any way we can use operator or regex as we normally do with the whereIn() clause.
I want to use something like this
$query->whereIN(name,'like','%test%');
I'm getting multiple data in an array. It should return data if name contains any of the keywords.
For eg. $searchArray = ['test','case'];
So it should return data with name containing values in $searchArray
Is it possible?
The whereIn method verifies that a given column's value is contained within the given array:
$users = DB::table('users')
->whereIn('id', [1, 2, 3])
->get();
https://laravel.com/docs/9.x/queries#additional-where-clauses
Try this:
where('title', 'like', '%' . $keyword . '%')
UPDATE:
$query->where(function ($query) use ($keyword, $columns) {
foreach ($columns as $key => $column) {
$clause = $key == 0 ? 'where' : 'orWhere';
$query->$clause($column, "LIKE", "%$keyword%");
if (!empty($relativeTables)) {
$this->filterByRelationship($query, $keyword,
$relativeTables);
}
}
});
I Had the same problem. The only way i was able do solve, was with mongodb native query aggregation. Let me show how i did.
I made a function to use in all of my system
public function matchLikeIn($match, $field, $value,$option = 'i')
{
try {
$or = array();
foreach($value as $v){
$or['$or'][] = [
$field => [
'$regex' => $v,
'$options' => $option
]
];
}
$match['$and'][] = $or;
return $match;
} catch (Exception $e) {
}
}
A exemple using it
$match = array();
$names = ["name1","name2"];
$match = $this->matchLikeIn($match, "name", $names, 'i');
$aggregate[] = ['$match' => $match];
$query = Model::raw(function ($collection) use ($aggregate) {
return $collection->aggregate($aggregate);
})->toArray();

get records from now till future

I want get all records that date alarm is now till future
I dont need records that have date alarm is in past
this is my Code:
$future=Carbon::now();
$time=$future->addMonth();
$records = document_date::where('date_alarm',$future)->whereHas('document')->with([
'document' => function ($query) {
$query->with([
'userClients' => function ($query) {
$query->where('type', 4)->with(['users']);
}
]);
}
])->orderBy('date', 'DESc')->get();
how can I do it?
use whereBetween( 'date_alarm' [$now , $future] ) instead of where
$now=Carbon::now();
$future=$now->addMonth();
$records = document_date::whereBetween('date_alarm' [$now , $future])->whereHas('document')->with([
'document' => function ($query) {
$query->with([
'userClients' => function ($query) {
$query->where('type', 4)->with(['users']);
}
]);
}
])->orderBy('date', 'DESc')->get();

Converting multiple same name into one single name using Laravel

I am trying to fetch the user name instead of multi user name but unfortunately, the single user name is not showing.
Controller
public function search(Request $request)
{
$date = explode(' - ', $request->date);
$auth = Auth::user();
$hourLog = Hourlog::with('project', 'user');
if ($request->user) {
$hourLog->whereIn("user_id", $request->user)->get();
} else if ($auth->user_type == 1) {
$hourLog->where("user_id", $auth->id);
}
if ($request->project) {
$hourLog->whereIn("project_id", $request->project)->get();
}
$data = [
"hourlogs" => $hourLog->whereBetween('date', $date)
->orderBy('date', 'desc')
->orderBy('start_time', 'asc')
->get(),
"date"=> $date,
];
return view('cms.projectreport.projectreport-list', $data);
}
html view
#foreach($hourlogs as $hourlog)
<tr>
<td>{{$hourlog->user->name}}</td>
</tr>
#endforeach
Use groupBy() on your query with the user_id:
$data = [
"hourlogs" => $hourLog->whereBetween('date', $date)
->orderBy('date', 'desc')
->orderBy('start_time', 'asc')
->groupBy('user_id')
->get(),
"date"=> $date,
];
This will give you a collection with unique user, containing the related models
You can use distinct to make the query like this:
$data = [
"hourlogs" => $hourLog
->select('user_id')
->whereBetween('date', $date)
->orderBy('date', 'desc')
->orderBy('start_time', 'asc')
->distinct()
->get(),
"date"=> $date,
];

Laravel: Selective drop down lists

So my drop down list works that I HAVE to select both options for it to display a list of hotels based on the criteria selected (Distance and price), but I want to make sure that the user can find all hotels based on just Price, for example. When I do this, no hotels appear and my drop down list doesn't quite work. So how would I exactly implement code that will let the user select all the hotels based on just the ONE criteria.
SearchController.php
public function index(Request $request)
{
$distances = DB::table('posts')->select('distance')->distinct()->get()->pluck('distance');
$prices = DB::table('posts')->select('price')->distinct()->get()->pluck('price');
$post = Post::query();
if ($request->has('price')) {
$post->where('price', $request->price);
}
if ($request->has('distance')) {
$post->where('distance', $request->distance);
}
return view('Pages.search', [
'distances' => $distances,
'prices' => $prices,
'posts' => $post->get(),
]);
}
Have you tried using when?
public function index(Request $request)
{
// Unnecessary select * changed to select only the columns you need.
$distances = DB::table('posts')->select('distance')->distinct()->get(['distance'])->pluck('distance');
$prices = DB::table('posts')->select('price')->distinct()->get(['price'])->pluck('price');
$post = Post::when($request->has('price'), function ($query) use ($request) {
$query->where('price', $request->price);
})
->when($request->has('distance'), function ($query) use ($request) {{
$query->where('distance', $request->distance);
})
->get();
/* php >= 7.4
$post = Post::when($request->has('price'), fn($query) => $query->where('price', $request->price))
->when($request->has('distance'), fn($query) => $query->where('distance', $request->distance))
->get();
*/
return view('Pages.search', compact('distances', 'prices', 'post');
}
So instead of the use of 'has' i simply implemented the 'filled' and this ensured that my filtering worked.

Resources