-
-
Save MrPunyapal/31433fdd415518f8510385b86178ff1f to your computer and use it in GitHub Desktop.
<?php | |
namespace App\Providers; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Support\Arr; | |
use Illuminate\Support\ServiceProvider; | |
class AppServiceProvider extends ServiceProvider | |
{ | |
/** | |
* Bootstrap any application services. | |
*/ | |
public function boot(): void | |
{ | |
// Define the 'whereLike' macro | |
Builder::macro('whereLike', function ($attributes, string $searchTerm) { | |
return $this->where(function (Builder $query) use ($attributes, $searchTerm) { | |
foreach (Arr::wrap($attributes) as $attribute) { | |
$query->when( | |
// Check if the attribute is not an expression and contains a dot (indicating a related model) | |
! ($attribute instanceof \Illuminate\Contracts\Database\Query\Expression) && | |
str_contains((string) $attribute, '.'), | |
function (Builder $query) use ($attribute, $searchTerm) { | |
// Split the attribute into a relation and related attribute | |
[$relation, $relatedAttribute] = explode('.', (string) $attribute); | |
// Perform a 'LIKE' search on the related model's attribute | |
$query->orWhereHas($relation, function (Builder $query) use ($relatedAttribute, $searchTerm) { | |
$query->where($relatedAttribute, 'LIKE', "%{$searchTerm}%"); | |
}); | |
// if need more deep nesting then commonet above code and | |
// use below (which is not recommend) | |
// Split the attribute into a relation and related attribute | |
// $attrs = explode('.', (string) $attribute); | |
// $relatedAttribute = array_pop($attrs); | |
// $relation = implode('.', $attrs); | |
// Perform a 'LIKE' search on the related model's attribute | |
// $query->orWhereRelation($relation, $relatedAttribute, 'LIKE', "%{$searchTerm}%"); | |
}, | |
function (Builder $query) use ($attribute, $searchTerm) { | |
// Perform a 'LIKE' search on the current model's attribute | |
// also attribute can be an expression | |
$query->orWhere($attribute, 'LIKE', "%{$searchTerm}%"); | |
} | |
); | |
} | |
}); | |
}); | |
} | |
} | |
// example of usage 👇 | |
Post::query() | |
->whereLike([ | |
'title', | |
// search in the current model's 'title' attribute | |
'description', | |
// search in the current model's 'description' attribute | |
'user.name', | |
// search in the related model's 'name' attribute | |
'user.email', | |
// search in the related model's 'email' attribute | |
DB::raw('DATE_FORMAT(created_at, "%d/%m/%Y")'), | |
// search in the formatted 'created_at' attribute | |
DB::raw('CONCAT(user.first_name, " ", user.last_name)'), | |
// search in the concatenated 'first_name' and 'last_name' attributes | |
], request()->search) | |
// search for the request's 'search' query parameter | |
->with('user') | |
->get(); |
Awesome tip.
For Laravel 8 you need to return the query builder otherwise all whereLike queries return null.
... return $this->where(function (Builder $query) use ($attributes, $searchTerm) { ...
thanks for sharing
Awesome tip.
instead of using:
$query->orWhereHas($relation, function (Builder $query) use ($relatedAttribute, $searchTerm) {
$query->where($relatedAttribute, 'LIKE', "%{$searchTerm}%");
});
use:
$query->orWhereRelation('comments.user' /*relation*/, 'name' /*column*/, 'LIKE', "%{$searchTerm}%");
instead of using:
[$relation, $relatedAttribute] = explode('.', (string) $attribute);
use:
$attrs = explode('.', (string) $attribute);
$relatedAttribute = array_pop($attrs);
$relation = implode('.', $attrs);
Post::query()
->whereLike([
'comments.user.name', // multiples relationships nested
'comments.user.address.name', // multiples relationships nested
'comments.user.address.city.name', // multiples relationships nested
...
Docs:
https://laravel.com/docs/10.x/eloquent-relationships#inline-relationship-existence-queries
n
Awesome tip.
instead of using:
$query->orWhereHas($relation, function (Builder $query) use ($relatedAttribute, $searchTerm) { $query->where($relatedAttribute, 'LIKE', "%{$searchTerm}%"); });
use:
$query->orWhereRelation('comments.user' /*relation*/, 'name' /*column*/, 'LIKE', "%{$searchTerm}%");
instead of using:
[$relation, $relatedAttribute] = explode('.', (string) $attribute);
use:
$attrs = explode('.', (string) $attribute); $relatedAttribute = array_pop($attrs); $relation = implode('.', $attrs);
Post::query() ->whereLike([ 'comments.user.name', // multiples relationships nested 'comments.user.address.name', // multiples relationships nested 'comments.user.address.city.name', // multiples relationships nested ...
Docs: https://laravel.com/docs/10.x/eloquent-relationships#inline-relationship-existence-queries
nice 🫡
public function render()
{
return view('livewire.admin.category-list',[
'categories' => Category::query()->whereLike(['name'], $this->search)
->latest()
->paginate($this->limit),
]);
}
I tried using the controller and livewire component, but neither of them worked and gave me an error.
Call to a member function latest() on null
public function render() { return view('livewire.admin.category-list',[ 'categories' => Category::query()->whereLike(['name'], $this->search) ->latest() ->paginate($this->limit), ]); } i used in livewire component ,its given me error Call to a member function latest() on null
Laravel version? 🤔
public function render() { return view('livewire.admin.category-list',[ 'categories' => Category::query()->whereLike(['name'], $this->search) ->latest() ->paginate($this->limit), ]); } i used in livewire component ,its given me error Call to a member function latest() on null
Laravel version? 🤔
"laravel/framework": "^10.0",
just add return
before $this->where
.....
Thankyou so much bro ,now its working 😊
Awesome tip.
For Laravel 8 you need to return the query builder otherwise all whereLike queries return null.
... return $this->where(function (Builder $query) use ($attributes, $searchTerm) { ...