Parameters Group on eloquent query - laravel

I have little problem with my search query at the moment. When i run a search query with only the parameter "comite_id" it's working but when i want to run the search query with "comite_id" and the whereBetween with "date_min" and "date_max" the result is not right , it's seems the result don't care about the whereBetween clause because i don't get the right date range.
Someone knows where i'm doing wrong? thanks a lot in advance
Here my controller :
public function getRetrocession(Request $request){
$comites = Structure::where('type_structure_id' , '=' ,'3')->pluck('nom_structure' , 'id');
$search = $request->input('comite_id');
$dt_min = $request->input('dt_min');
$dt_max = $request->input('dt_max');
if ($search) {
$query = Retrocession::where('comite_id', '=', $search)
->orWhere(function ($q) use($search , $dt_min , $dt_max) {
$q->where('comite_id', '=', $search)
->whereBetween('dt_retrocession', [ $dt_min , $dt_max]);
});
}else {
$query = Retrocession::select();
}
$retrocessions = $query->orderBy('dt_retrocession', 'DESC')->paginate(10)
->appends(['recherche' => $search]);
return view('retrocession/index' , compact('retrocessions' , 'comites'));
}

Because you are using orWhere() it always call both where() and orWhere(); thus including the result of where() and orWhere(). You can try this way
$query = Retrocession::where('comite_id', $search)
->when($dt_min && $dt_max, function($q) use ($dt_min, $dt_max) {
$q->whereBetween('dt_retrocession', [$dt_min, $dt_max]);
});
So you always run the first where, and only include whereBetween() WHEN $dt_min and $dt_max are both true.
Bonne chance Mathieu.

Related

use like on laravel can't display date search

i want to search data based nama_kegiatan or tanggal_kegiatan where these two name form my table field, this code from my controller :
public function search(Request $request){
$cari = $request->search;
$caritanggal = date($request->datekeg);
$infokeg = Infokeg::where(function ($query) use ($cari) {
$query->where('nama_kegiatan','like',"%$cari%")->get();
})->orWhere(function($query) use ($caritanggal) {
$query->where('tanggal_kegiatan', $caritanggal)->get();;
})->paginate(10);
return view('infokeg/infokeg', ['infokeg' => $infokeg]);
}
when i am using like on nama_kegiatan, tanggal_kegiatan didnt work and just display all data, but when i delete like from nama_kegiatan, its work, but i cant search nama_kegiatan using like, so how to solve it ?
Maybe you can try to get() all the result after the query? Somethings like
$infokeg = Infokeg::where('name_kegiatan','LIKE','%'.$cari.'%')->orWhere('tanggal_kegiatan',$caritanggal)->get();
IMO the get() and paginate() cannot be use at the same time if I have not get it wrong. If you need to paginate after all the result, you can do create Paginator manually. Maybe this link can help you. Hope this will help you and please correct me if anything wrong. Thanks!
If you want to see what is run in the database use dd(DB::getQueryLog()) after query to see what queries exactly were run.
$infokeg = Infokeg::where('nama_kegiatan','like', "%" . $cari ."%")
->orWhere(function($query) use ($caritanggal) {
$query->where('tanggal_kegiatan', $caritanggal);
})->paginate(10);
just make it into if condition
public function search(Request $request)
{
$cari = $request->search;
$caritanggal = $request->datekeg;
if (isset($cari)) {
$infokeg = Infokeg::where('nama_kegiatan', 'like', '%'.$cari.'%')
->paginate(5);
}elseif (isset($caritanggal)) {
$infokeg = Infokeg::where('tanggal_kegiatan', 'like', '%'.$caritanggal.'%')
->paginate(5);
}elseif (isset($cari)&&isset($caritanggal)) {
$infokeg = Infokeg::where('nama_kegiatan', 'like', '%'.$cari.'%')
->orWhere('tanggal_kegiatan', 'like', '%'.$caritanggal.'%')
->paginate(5);
}
return view('/admin/infokeg/infokeg', ['infokeg' => $infokeg]);
}

Eloquent where condition AND ( condition OR condition OR condition )

Can somebody tell me what am I doing wrong?
I want to get all projects with status 0 and if any of data matches in eloquent.
My code is like this
public function search(Request $request){
if($request->has('q')){
$search_query = $request->input('q');
$projects = Project::where(['status' => '0'])->get();
$projects = $projects->where(function($query) use ($search_query) {
$query->where('title','LIKE','%'.$search_query.'%')
->orWhere('shortDescription','LIKE','%'.$search_query.'%')
->orWhere('longDescription','LIKE','%'.$search_query.'%')
->orWhere('tags','LIKE','%'.$search_query.'%')
->orWhere('projectLink','LIKE','%'.$search_query.'%');
});
$projects->get();
dd($projects);
}
}
And I am getting this error
ErrorException
explode() expects parameter 2 to be string, object given
I solved the problem but changed the code a little bit... If you like, take it! I tested and it's working.
if($request->has('q')){
// Your $request->q Value
$term = $request->q;
$projects = DB::table('tbl_projects')->where('status', '=', 0)
->where(function ($query) use ($term) {
$query->where('title', 'LIKE', '%'.$term.'%')
->orWhere('shortDescription', 'LIKE', '%'.$term.'%')
->orWhere('longDescription', 'LIKE', '%'.$term.'%')
->orWhere('tags', 'LIKE', '%'.$term.'%')
->orWhere('projectLink', 'LIKE', '%'.$term.'%');
})
->get();
//dd($projects);
}
Raw query is:
select * from `tbl_projects` where `status` = 0 and (`title` LIKE %bla bla% or `shortDescription` LIKE %bla bla% or `longDescription` LIKE %bla bla% or `tags` LIKE %bla bla% or `projectLink` LIKE %bla bla%))
Regards!
Your error is
$projects = Project::where(['status' => '0'])->get();
(['status' => '0']) Where clause params required is different. You must use ('status', '0') or ('status', '=', '0')
When you use ->get(), you have a Collection or EloquentCollection object. You need a QueryBuilder
Try to implement a better programation logic.
A better implementation is
public function search(Request $request){
if($request->has('q')){
// Add array with field coincidences target. Is better if this array is a const static field in the Project model
$searchFields = ['title', 'shortDescription', 'longDescription', 'tags', 'projectLink' ];
// Now you can add 100 fields for search coincidences easily
$search_query = $request->input('q');
$projects = Project::where('status', '0');
foreach($searchFields as $searchField){
if ($searchField == 'title'){
$projects = $projects->where($searchField,'LIKE',"%$search_query%");
continue;
}
$projects = $projects->orWhere($searchField,'LIKE',"%$search_query%");
}
$projects = $projects->get();
dd($projects);
}
}

Laravel eloquent using loop

I am using eloquent query to filter data. My query is like this and it is working perfectly for now.
$users = User::where('username','LIKE','%'.request('username').'%')
->where('first_name','LIKE','%'.request('first_name').'%')
->where('last_name','LIKE','%'.request('last_name').'%')
->where('gender','LIKE','%'.request('gender').'%')
->where('password','LIKE','%'.request('password').'%')
->SimplePaginate(15);
My request data was like this.
However I need to update this query for dynamic fields. There can be different fields. What I did was to send the request in an associative array. So, my request data turned into like this,
What I intend to do is to put all request data in a search array. Then use a loop to run like the above query. How can I do that?
P.S. I checked in the forum and found some similar questions. Some of them are outdated. Others didn't solve my problem.
If I understand you right you can do like this:
$search = request('search', []);
$users = User::query();
foreach($search as $field=>$value)
{
$users = $users->where($field,'LIKE','%'.$value.'%');
}
$users = $users->SimplePaginate(15);
You can try this.
$search = $request->get('search');
User::where(function ($q) use ($search){
foreach ($search as $key=>$value) {
if($value != null ){
$q->where($key, 'like', "%{$value}%");
}
}
})->get();
The where() clause can also accept an array. With that in mind, you could map over your search parameters and convert it to the format you want and then feed it into the query.
For example:
$search = [
'first_name' => 'John',
'last_name' => 'Smith'
];
$filters = collect($search)->map(function($value, $key) {
return [$key, 'LIKE', "%{$value}%"];
})->values()->toArray();
return User::where($filters)->SimplePaginate(15);

Condition in a search query doesn't work

I have a search query fonction who seems to not work with the last condition . (->where('structure_id' , '=' , $mastructure);
I fact when i run the query i get also the other licences from other "structure_id "
here my search controller
public function getLicenciesStructure(Request $request){
$mastructure = Auth::user()->structure->id ;
$search = $request->get('recherche');
if ($search) {
$query = Licencies::Where('lb_nom', 'like', "%$search%")->orWhere('num_licence' , 'like' , "%$search%")->where('structure_id' , '=' , $mastructure);
}
$licenciestructures = $query->paginate(10)
->appends(['recherche' => $search]);
return view('licencie_structure/index' , compact('licenciestructures' , 'mastructure'));
}
Someone have an idea why the query display also the other items from other structure_id ? thanks a lot in advance
Use where() closure:
Licencies::where(function($q) use($search) {
$q->where('lb_nom', 'like', '%'.$search'%')
->orWhere('num_licence', 'like', '%'.$search.'%');
})->where('structure_id', $mastructure);

Laravel 4 - Eloquent 'where' only if exists

I'm working in a search engine, and I have something like this in my Controller:
$user = User::where('description', 'LIKE', '%'.$keyword.'%')
->where('position', $position)
->where('age', $age)
->orderBy('created_at', 'DES')
->paginate(10);
What I want is to use the $position and $age filters only if they exist. I mean, if I only set the keyword, I expect the application to show me all the users with this keyword (whatever its position and age are).
I know a way to do it... using if($position == '')... else..., but I would like to do (if possible) in my Eloquent consult. Something like... ->where('position' ? $position).
Any idea how to do it in the simplest way?
Thanks in advance!
Using if conditions would be the best way to do this. As far as I know the functionality your after isn't built into Eloquent.
I would do it using conditionals like so:
$query = User::where('description', 'LIKE', '%'.$keyword.'%');
if($position) {
$query->where('position', $position);
}
if($age) {
$query->where('age', $age);
}
$user = $query->orderBy('created_at', 'DES')->paginate(10);
If you want to keep your controller clean and avoid if - else you can create some scopes in your model.
For exemple :
public function scopePosition($query, $position)
{
//If $position in empty, return the query without where clause
return !($position == '') ? $query->where('position', $position) : $query;
}
And :
public function scopeAge($query, $age)
{
//If $age in empty, return the query without where clause
return !($age== '') ? $query->where('age', $age) : $query;
}
And then use it like this:
$user = User::where('description', 'LIKE', '%'.$keyword.'%')
->position($position)
->age($age)
->orderBy('created_at', 'DES')
->paginate(10);
More abour query scope:
http://laravel.com/docs/eloquent#query-scopes

Resources