Where clauses and search - laravel

I'm new in Laravel and Livewire. I have problem with my code, I'm trying to use where clauses and search in one query. I have code like this.
This is in my controller
public function read()
{
return Groom::query()
->search($this->search)
->orderBy($this->sortBy, $this->sortDirection)
->paginate($this->perPage);
}
and this one in my model
public function scopeSearch($query, $val)
{
return $query
->where('status', '<>', 'selesai')
->leftJoin('pets', 'pets.id', '=', 'grooms.pet_id')
->where('name', 'like', '%' .$val. '%')
->where(function ($query) use ($val) {
$query
->Orwhere('service', 'like', '%'. $val. '%')
->Orwhere('address', 'like', '%' .$val. '%')
->Orwhere('status', 'like', '%' .$val. '%');
});
}
There's no error there, but my search isn't working

Your generated SQL query is
select * from grooms
left join "pets" on "pets"."id" = "grooms"."pet_id"
where "status" <> 'selesai'
and "name" like ? and (
"service" like ?
or "address" like ?
or "status" like ?
)
order by ...
Perhaps you want the name filter to be inside that grouped where? Try
public function scopeSearch($query, $val)
{
return $query
->where('status', '<>', 'selesai')
->leftJoin('pets', 'pets.id', '=', 'grooms.pet_id')
->where(function ($query) use ($val) {
$query
->orWhere('name', 'like', '%' .$val. '%')
->orwhere('service', 'like', '%'. $val. '%')
->orwhere('address', 'like', '%' .$val. '%')
->orwhere('status', 'like', '%' .$val. '%');
});
}

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;
}

Laravel whereDate() is not working as expected

The following is part of my query for querying data between two dates:
->whereDate('fixture_date', '>=', Carbon::now()->subDays($pastDays))
->whereDate('fixture_date', '<=', Carbon::now()->addDays($futureDays))
->when(request('search'), function ($query) {
$query->orWhere('fixture_hometeam_name', 'LIKE', '%' . request('search') . '%')
->orWhere('fixture_awayteam_name', 'LIKE', '%' . request('search') . '%');
})
When request('search') is empty, I am getting the expected results but when not, the whereDate queries are not working.
How should this be modified to give the correct results?
Add another layer to add parenthesis around the orWhere of the search.
->whereDate('fixture_date', '>=', Carbon::now()->subDays($pastDays))
->whereDate('fixture_date', '<=', Carbon::now()->addDays($futureDays))
->when(request('search'), function ($query) {
$query->where(function($subQuery) {
$subQuery->orWhere('fixture_hometeam_name', 'LIKE', '%' . request('search') . '%')
->orWhere('fixture_awayteam_name', 'LIKE', '%' . request('search') . '%');
})
})
You can use whereBetween instead of two whereDate.
->whereBetween('fixture_date', [
now()->subDays($pastDays)->startOfDay(), now()->addDays($futureDays)->endOfDay()
])->when($request->search, function ($query, $search) {
return $query->where(function ($query) use ($search) {
$query->where('fixture_hometeam_name', 'like', "%{$search}%")
->orWhere('fixture_awayteam_name', 'like', "%{$search}%");
});
https://laravel.com/docs/8.x/queries#logical-grouping
You should always group orWhere calls in order to avoid unexpected behavior when global scopes are applied.

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);
}

search function with Where clause not work

hello everyone i try to run a search query with a condition for my column 'structure_id' but when i run the query , it display me also results who are not from 'structure' = 4
here my query :
$search = $request->get('q');
return User::where(function($q) use($search) {
$q->where('name', 'like', '%' . $search .'%')
->orWhere('email', 'like', '%'.$search.'%')
->where('structure_id' , '=' , '4');
})->get();
someone have an idea to resolve this? thanks a lot in advance
change it to
$search = $request->get('q');
return User::where(function($q) use($search) {
$q->where('name', 'like', '%' . $search .'%')
->orWhere('email', 'like', '%'.$search.'%');
})
->where('structure_id' , '=' , '4')
->get();

Laravel eloquent search on fields of related model

I have an eloquent models as,
User : users(id, username, password, email, status)
Profile : profiles(id, user_id, first_name, last_name, gender, dob)
In the controller logic, I am eagerly loading the Profile model.
I can do this,
$user = User::with('Profile')->get();
or
$user = User::with('Profile')->where('status', '1')->get();
but how to do something like,
$user = User::with('Profile')->where('status', '1')->where('gender', 'Male')->get();
That's where whereHas comes in handy:
$user = User::with('Profile')->where('status', 1)->whereHas('Profile', function($q){
$q->where('gender', 'Male');
})->get();
Basically it adds the condition that the user needs to have a profile with gender = Male
If you want to search multiple columns in relation model.
$searchText = 'test text';
Product::with('owner')->where(function($query) use ($searchText)
{
$query->where('product_name', 'LIKE', '%' . $searchText . '%');
$columns = ['product_code', 'place_location', 'remark'];
foreach ($columns as $column ) {
$query->orWhere($column, 'LIKE', '%' . $searchText . '%');
}
$query->orWhereHas('owner', function($q) use ($searchText) {
$q->where(function($q) use ($searchText) {
$q->where('name', 'LIKE', '%' . $searchText . '%');
$q->orWhere('company_name', 'LIKE', '%' . $searchText . '%');
});
});
});
Let's say you've multiple relations
and you want to search records based on multiple relational columns value
User::with('associate')
->where('name', 'like', '%' . $input . '%')
->orWhere(function ($query) use ($input) {
$query->whereHas('associate', function ($q) use ($input) {
$q->where('first_name', 'like', '%' . $input . '%');
});
})
->orWhere(function ($query) use ($input) {
$query->with('roles')->whereHas('roles', function ($q) use ($input) {
$q->where('display_name', 'like', '%' . $input . '%');
});
})
->get();
Suppose, Your search input field name is q.
function name(Request $request){
$query = User::select();
if($request->q && $request->q !=''){
// if you search
$keyword = $request->q;
$query = User::with('Profile')->whereHas('Profile', function($q) use
($keyword){
$q->where('gender', 'like', "%{$keyword}%" );
});
}
$query->latest('id')->paginate();
}

Resources