Laravel eloquent real time search filtering - laravel

I'm trying to make a server-side searching and came up with this eloquent query...
public function search(Request $request) {
$data = User::with('instruments')
->where('user_type', 'teacher')
->orWhere('fname', 'like', '%' . $request->term . '%' )
->orWhere('fname', 'like', $request->term . '%' )
->orWhere('lname', 'like', '% ' . $request->term . '%' )
->orWhere('lname', 'like', $request->term . '%' )
->orWhere('email', 'like', '% ' . $request->term . '%' )
->orWhere('email', 'like', $request->term . '%' )
->orWhere('profession', 'like', '%' . $request->term . '%' )
->orWhere('profession', 'like', $request->term . '%' )
->limit(10)
->get();
return response()->json($data);
}
I almost achieved what I wanted. For example, when I search john it gives me all the users with john in their name. The problem is that, tho the search is correct and knowing I declared where('user_type', 'teacher'), the result set still gives me users with student user_type

The problem is that the OrWhere nullifies the user_type condition, that's why it selects users that are not teachers when one of the OrWhere conditions applies.
By using a second where with a closure, it will always only select users with a user_type teacher:
public function search(Request $request)
{
$data = User::with('instruments')
->where('user_type', 'teacher')
->where(function ($query) use ($request) {
$query->where('fname', 'like', '%' . $request->term . '%')
->orWhere('fname', 'like', $request->term . '%')
->orWhere('lname', 'like', '% ' . $request->term . '%')
->orWhere('lname', 'like', $request->term . '%')
->orWhere('email', 'like', '% ' . $request->term . '%')
->orWhere('email', 'like', $request->term . '%')
->orWhere('profession', 'like', '%' . $request->term . '%')
->orWhere('profession', 'like', $request->term . '%');
})
->limit(10)
->get();
return response()->json($data);
}

Related

searching on name instead of id on sql

I have search input in my products page. I can search on name on description and on category if I type the id but that's not really practical how i change this sql so i can search on the name of the category instead of the id.
DB i have Products | name,description,category_id
Categories | id,name
public function scopeFilter($query,array $filters){
if ($filters['search'] ?? false){
$query
->where('name', 'like', '%' . request('search') . '%')
->orWhere('description', 'like', '%' . request('search') . '%')
->orWhere('category_id', 'like', '%' . request('search'). '%');
}
}
Since the category is a related model search on the relationship:
public function scopeFilter($query,array $filters){
if ($filters['search'] ?? false){
$query
->where('name', 'like', '%' . request('search') . '%')
->orWhere('description', 'like', '%' . request('search') . '%')
->orWhereHas('category', function ($q) {
$q->where('name','like', '%' . request('search'). '%'
});
}
}
This is assuming you have defined your relationship in your model.
Since the category is a related model search on the relationship AND I suggest using this code: ‌
public function scopeFilter($query,array $filters) {
if ($filters['search'] ?? false){
return $query->where('name', 'like', '%' . request('search') . '%')
->orWhere('description', 'like', '%' . request('search') . '%')
->orWhereHas('category', function ($q) {
$q->where('name','like', '%' . request('search'). '%');
});
}
return $query;
}

How to search using session with multiple table with where caluse using Laravel?

How to do this?
**This code is working **
$posts = NewJob::with(['client_info','office_info'])
->orderBy('won', 'desc')
->where('progress' , 'forwarded')
->where('won', 'like', '%' . $request->session()->get('search') . '%')
->paginate(5);
========================================================================
But when I added more where clause then displaying the blank results.
$posts = NewJob::with(['client_info','office_info'])
->orderBy('won', 'desc')
->where('progress' , 'forwarded')
->where('won', 'like', '%' . $request->session()->get('search') . '%')
->where('proj_name', 'like', '%' . $request->session()->get('search') . '%')
->paginate(5);
This way you can do it.
You can also use one orWhere condition instead of two, according to your need.
$posts = NewJob::with('client_info','office_info')
->orderBy('won', 'desc')
->where('progress' , 'forwarded')
->where('won', 'like', '%' . $request->session()->get('search') . '%')
->orWhere('proj_name', 'like', '%' . $request->session()->get('search') . '%')
->paginate(5);
For joins mean to say relations you can do it something like this.
I have written the code for one of your model, you can do it for other models same like this, and also you can use the closure function in with() function as well. Also you can use orWhereHas on different models as well.
$posts = NewJob::whereHas('client_info', function($query){
$query->where('something','is_something'); //query conditions on other table
$query->orWhere('something','is_something');
})
->orderBy('won', 'desc')
->where('progress' , 'forwarded')
->where('won', 'like', '%' . $request->session()->get('search') . '%')
->orWhere('proj_name', 'like', '%' . $request->session()->get('search') . '%')
->paginate(5);

Laravel Eloquent query ignoring column value

On my search method in the Models\Article::class I'm able to get all the results, even in the multiple relations with Categories and Tags, but the issue, that I've been trying to solve, unsuccessfully, is that I just want the results for the published articles – my db column for this is a bool 'active'.
I've tried different approaches by switching the ->where('active', 1) clause around but the results are the same. It brings all the active and non active.
I have in development 8 articles but only 7 with active = 1. When I perform the search, the response sends all the 8, ignoring the where('active', 1) clause. Probably I'm missing or messing something here in the following method:
// Method in the Article Model class
public function getSearchResults($query)
{
return $this->where('active', 1)->where('start_publishing', '<=', Carbon::now())
->where('external_reference', 'LIKE', '%' . $query . '%')
->orWhere('byline', 'LIKE', '%' . $query . '%')
->orWhere('published_by', 'LIKE', '%' . $query . '%')
->orWhere('title', 'LIKE', '%' . $query . '%')
->orWhere('subhead', 'LIKE', '%' . $query . '%')
->orWhere('lead_story', 'LIKE', '%' . $query . '%')
->orWhere('content', 'LIKE', '%' . $query . '%')
->orWhere('meta_keywords', 'LIKE', '%' . $query . '%')
->with('categories')->orWhereHas('categories', function ($q) use ($query) {
$q->where('title', 'LIKE', '%' . $query . '%');
})
->with('documents')->orWhereHas('documents', function ($q) use ($query) {
$q->where('doc_title', 'LIKE', '%' . $query . '%');
//$q->where('doc_description', 'LIKE', '%'.$query.'%');
})
->with('tags')->orWhereHas('tags', function ($q) use ($query) {
$q->where('name', 'LIKE', '%' . $query . '%');
})
->with('images')
->orderBy('type', 'desc')
->orderBy('updated_at', 'desc')
->paginate(15);
}
Thanks in advance fr any help here on this issue.
Result is because you are use orWhere Criteria. For fix it use this
$this->where('active', 1)
->where('start_publishing', '<=', Carbon::now())
->where(function($q) use ($query) {
$q->where('external_reference', 'LIKE', '%' . $query . '%') // the $q here is required
->orWhere('byline', 'LIKE', '%' . $query . '%')
->orWhere('published_by', 'LIKE', '%' . $query . '%')
->orWhere('title', 'LIKE', '%' . $query . '%')
->orWhere('subhead', 'LIKE', '%' . $query . '%')
->orWhere('lead_story', 'LIKE', '%' . $query . '%')
->orWhere('content', 'LIKE', '%' . $query . '%')
->orWhere('meta_keywords', 'LIKE', '%' . $query . '%');
})
->with('categories')->orWhereHas('categories', function ($q) use ($query) {
$q->where('title', 'LIKE', '%' . $query . '%');
})
->with('documents')->orWhereHas('documents', function ($q) use ($query) {
$q->where('doc_title', 'LIKE', '%' . $query . '%');
//$q->where('doc_description', 'LIKE', '%'.$query.'%');
})
->with('tags')->orWhereHas('tags', function ($q) use ($query) {
$q->where('name', 'LIKE', '%' . $query . '%');
})
->with('images')
->orderBy('type', 'desc')
->orderBy('updated_at', 'desc')
->paginate(15);
Ok, after Davit's suggestion, which at the beginning seemed like to work, but it was the query I was doing that was "faking" the results, I finally managed to make it work.
Taking the code David suggested, I made a few changes, through the logic of how the query gets constructed and ended up with a final working method that will return only the active Articles matching the "query" criteria from the request. Below the final method code:
// Method in the Article Model class
public function getSearchResults($query)
{
return $this->where('active', 1)
->where('start_publishing', '<=', Carbon::now())
->where(function ($q) use ($query) {
$q->where('external_reference', 'LIKE', '%' . $query . '%')
->orWhere('byline', 'LIKE', '%' . $query . '%')
->orWhere('published_by', 'LIKE', '%' . $query . '%')
->orWhere('title', 'LIKE', '%' . $query . '%')
->orWhere('subhead', 'LIKE', '%' . $query . '%')
->orWhere('lead_story', 'LIKE', '%' . $query . '%')
->orWhere('content', 'LIKE', '%' . $query . '%')
->orWhere('meta_keywords', 'LIKE', '%' . $query . '%');
$q->with('categories')->orWhereHas('categories', function ($q) use ($query) {
$q->where('title', 'LIKE', '%' . $query . '%');
});
$q->with('documents')->orWhereHas('documents', function ($q) use ($query) {
$q->where('doc_title', 'LIKE', '%' . $query . '%');
//$q->where('doc_description', 'LIKE', '%'.$query.'%');
});
$q->with('tags')->orWhereHas('tags', function ($q) use ($query) {
$q->where('name', 'LIKE', '%' . $query . '%');
});
})
->with('categories')
->with('tags')
->with('images')
->distinct()
->orderBy('type', 'desc')
->orderBy('updated_at', 'desc')
->paginate(15);
}

Multiple where inside a where statement

I would like to generate a query in Laravel that gives the following results:
From the results obtained from
$results = DB::table('records')->where('email', '!=', 'test#gmail.com')->get();
Do multiple where statements like this:
->where('id', 'like', '%'.$request->search.'%')
->orWhere('email', 'like', '%'.$request->search.'%')
->orWhere('recordType', 'like', '%'.$request->search.'%')
->orWhere('uploadDate', 'like', '%'.$request->search.'%')
->orWhere('uploadTime', 'like', '%'.$request->search.'%')
->get();
How should I phrase the statement in controller to produce the desired result?
Use the where() closure to group parameters:
$results = DB::table('records')->where('email', '!=', 'test#gmail.com')
->where(function($q) use($request) {
$q->where('id', 'like', '%' . $request->search . '%')
->orWhere('email', 'like', '%' . $request->search . '%')
->orWhere('recordType', 'like', '%' . $request->search . '%')
->orWhere('uploadDate', 'like', '%' . $request->search . '%')
->orWhere('uploadTime', 'like', '%' . $request->search . '%');
})
->get();

Laravel sort model by one to many relationship

I have two models Location and Danger
Danger has two fields location_id and user_id it simply save users report about locations
btw Danger has a one to many relation with Location
the question is
how can I sort locations with count of it's danger in a search form
here is my form:
$locations = Location::latest();
if ($request->get('q')) {
$q = $request->get('q');
$locations->where('desc', 'like', '%' . $q . '%')
->orWhere('name', 'like', '%' . $q . '%');
}
$locations=$locations->paginate(12);
return view('list')->with(compact('locations'));
If your location has many danger and your relation is named dangers then you can use withCount() for sorting as:
$locations = Location::withCount('dangers');
if ($request->get('q')) {
$q = $request->get('q');
$locations->where('desc', 'like', '%' . $q . '%')
->orWhere('name', 'like', '%' . $q . '%');
}
$locations->orderBy('dangers_count', 'desc')
$locations=$locations->paginate(12);
this might work.
$locations = Location::latest();
if ($request->get('q')) {
$q = $request->get('q');
$locations->where('desc', 'like', '%' . $q . '%')
->orWhere('name', 'like', '%' . $q . '%');
$locations->sortBy(function($item, $key){
return $location->danger()->count();
})
}
$locations=$locations->paginate(12);
return view('list')->with(compact('locations'));

Resources