Livewire checkbox filter to relation model - laravel

I have a Livewire component with search field whick works like a charm, and above that I have a list of Location model. /locations. Also, I have a relation table Categories with category_id. Now, i want to implement checkbox filter on same page with category (catA, catB, catC). I maked a Livewire component with
PLease can you help me. Thanky much
class LocationSearch extends Component
public $searchTerm = "";
public $locations;
public $categories = [];
public function render()
{
sleep(1);
$searchTerm = '%' . $this->searchTerm . '%';
$this->locations = Location::query()
->where('name', 'LIKE', "%{$searchTerm}%")
->orWhere('description', 'LIKE', "%{$searchTerm}%")
->orWhere('visibility', 'LIKE', "%{$searchTerm}%")
->get();
return view('livewire.location-search', [
]);
}

Related

How can I render search on Livewire with an orWhere clause not related to search?

I have here a Livewire render function that displays records depending on what is searched on the textbox. It was working fine, and giving me results in an autocomplete manner. However, when I added this line ->orWhere('qty_on_hand', '!=', 0), it stops that autocomplete searching.
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Product;
class LoadInStockProducts extends Component
{
public $searchTerm;
public $amount = 10;
protected $listeners = [
'load-more' => 'loadMore'
];
public function loadMore()
{
$this->amount = $this->amount + 10;
}
public function render()
{
$searchTerm = '%' . $this->searchTerm . '%';
$products = Product::orderBy('name')->where('code', 'like', $searchTerm)
->orWhere('name', 'like', $searchTerm)
->orWhere('description', 'like', $searchTerm)
->orWhere('qty_on_hand', '!=', 0)
->paginate($this->amount);
$this->emit('productStore');
return view('livewire.load-in-stock-products', ['products' => $products]);
}
}
How can I make the autocomplete searching work, even with the ->orWhere('qty_on_hand', '!=', 0) condition? Also, another question, I've tried this ->orWhere('srp', '!=', 0.00) and it's not working. How can I make it work for float types? The srp field is a float type by the way.
Any help is much appreciated.
It sounds to me like you want to produce a query where you search for the given fields, and only show the records that has a quantity on hand - that would look like this in raw SQL,
SELECT *
FROM products
WHERE (
code LIKE '%searchterm%'
OR name LIKE '%searchterm%'
OR description LIKE '%searchterm%'
)
AND qty_on_hand != 0
ORDER BY name
Note how the search for code/name/description is within its own group, and that you look for any match of either of those and where the quantity is different from zero.
In Laravel, that means you have to group the query as well, using a closure.
$products = Product::where(function($query) use ($searchTerm) {
return $query->where('code', 'like', $searchTerm)
->orWhere('name', 'like', $searchTerm)
->orWhere('description', 'like', $searchTerm);
})
->where('qty_on_hand', '!=', 0)
->orderBy('name')
->paginate($this->amount);
You can introduce more groups if you have other conditions, like having two where() with a closure, where the queries inside use orwhere().
$products = Product::where(function($query) use ($searchTerm) {
return $query->where('code', 'like', $searchTerm)
->orWhere('name', 'like', $searchTerm)
->orWhere('description', 'like', $searchTerm);
})
->where(function($query) {
return $query->where('qty_on_hand', '!=', 0)
->orWhere('srp', '!=', 0);
})
->orderBy('name')
->paginate($this->amount);

Select User by Profile name in Laravel way

I have models User and Profile with hasOne relationship as following:
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class, 'user_id');
}
}
I want to select all users by full_name attribute of Profile in Laravel way. I have tried to this code but it return all the users in user table.
User::with(['profile' => function ($q) use ($request) {
$q->where('last_name', 'LIKE', '%' . $request->input('name') . '%');
}]);
Any idea? Thanks so much.
Try whereHas method like:
User::whereHas('profile', function($q) use($request) {
$q->where('last_name', 'LIKE', '%' . $request->input('name') . '%');
});

How to group where clauses in Laravel Query Builder correctly

I am running the following query using the search() function below - the problem is I need to group the where clauses - what am I doing wrong?
select `standings`.*, `users`.`name` as `user` from `standings`
left join `users` on `standings`.`user_id` = `users`.`id`
where `users`.`name` like '%bob%' or `users`.`email` like '%bob%'
and `standings`.`tenant_id` = '1'
In my Standings model I have the following search() that performs the WHERE clause
public static function search($query)
{
return empty($query) ? static::query()
: static::where('users.name', 'like', '%'.$query.'%')
->orWhere('users.email', 'like', '%'.$query.'%');
}
public function render()
{
$query = Standing::search($this->search)
->select('standings.*', 'users.name AS user')
->leftJoin('users', 'standings.user_id', '=', 'users.id')
->orderBy('points', 'desc')
->orderBy('goals_difference', 'desc')
->orderBy('goals_for', 'desc');
if($this->super && $this->selectedTenant) {
$query->where('standings.tenant_id', $this->selectedTenant);
}
return view('livewire.show-standings', [
'standings' => $query->paginate($this->perPage)
]);
}
The query works however it doesn't group the WHERE clause correctly on the users.name & users.email fields - how do I change this search() function so the WHERE query has them grouped like this
where (`users`.`name` like '%bob%' or `users`.`email` like '%bob%')`
You need to group the where clauses in a wrapping where clause. Try this
public static function search($query)
{
return empty($query)
? static::query()
: static::where(function($query){
$query->where('users.name', 'like', '%'.$query.'%')
->orWhere('users.email', 'like', '%'.$query.'%');
});
}
Thanks that for some reason even though looks correct gives me the following error - Object of class Illuminate\Database\Eloquent\Builder could not be converted to string NB I am using Laravel with Livewire (not sure if that should make any difference)
$query->where('users.name', 'like', '%'.$query.'%') and ->orWhere('users.email', 'like', '%'.$query.'%'); is giving the error because while trying to compare $query is being treated as a string hence the error
You can define the search as a query scope on the model
//Assuming a relation Standing belongsTo User
//Query constraint to get all Standing records where
//related User record's name or email are like searchTerm
public function scopeSearch($query, string $searchTerm)
{
return $query->whereHas('user', function($query) use($searchTerm){
$query->where('name', 'like', "%{$searchTerm)%")
->orWhere('email', 'like', "%{$searchTerm}%");
});
}
Laravel docs:https://laravel.com/docs/8.x/eloquent#local-scopes
With the above search scope defined on Standing model, you can have the render function as
public function render()
{
$query = Standing::with('user:id,name')
->search($this->search)
->orderBy('points', 'desc')
->orderBy('goals_difference', 'desc')
->orderBy('goals_for', 'desc');
if($this->super && $this->selectedTenant) {
$query->where('tenant_id', $this->selectedTenant);
}
return view('livewire.show-standings', [
'standings' => $query->paginate($this->perPage)
]);
}

How to search into hasMany relationship in laravel

I have a model of Company and Dispensary
<?php
// Company.php
public function dispensary()
{
return $this->hasMany(Dispensary::class);
}
// Dispensary.php
public function company()
{
return $this->belongsTo(Company::class);
}
What I want is first get the dispensary of the company which the user belongs.
$auth = \Auth::user();
$userCompany = $auth->company()->get();
$dispensaries = Company::find($userCompany->first()->id)->dispensary;
How should I construct a query where the user can search for the dispensary list where the user belongs.
I have tried using whereHas but it's searching from the Company instead of the Dispensary
Company::find($userCompany->first()->id)
->whereHas('dispensary', function ($query) use ($name) {
$query->where('name', 'like', "%{$name}%");
})->get();
Okay I finally made it to work just by using where clause
$company = Company::find($id)->dispensary()
->where('name', 'like', "%{$name}%")
->where('contact_email', 'like', "%{$email}%")
->get();

where clause inside a relationships - laravel

I have 3 models like this:
WarehousePivotCategory:
id - warehouse_id - warehouse_category_id
Warehouse:
title
WarehouseCategory:
title_en
I've created 2 hasOne relationships inside WarehousePivotCategory and they work fine:
public function Warehouse()
{
return $this->hasOne('App\Models\Warehouse','id','warehouse_id');
}
public function WarehouseCategory()
{
return $this->hasOne('App\Models\WarehouseCategory','id','warehouse_category_id');
}
in the database I have two records in warehouses table :
id title
1 AA
2 BB
I want to search title in warehouses :
$title = 'AA';
$warehouses = WarehousePivotCategory::with(['warehouse' => function($q) use ($title) {
$q->where('title', 'like', '%' . $title . '%');
},'WarehouseCategory'])->get();
foreach ($warehouses as $w)
{
echo $w->warehouse->title; // no thing
}
but it doesn't return any of title of warehouses.
my relationships is correct because below code works fine :
WarehousePivotCategory::with('warehouse','WarehouseCategory')->paginate(10);
I think you're missing get method in your closure. Try it like this:
$warehouses = WarehousePivotCategory::with(['warehouse' => function($q) use ($title) {
$q->where('title', 'like', '%' . $title . '%')->get(); },'WarehouseCategory'])->get();
You can also send array of fields you want to fetch to get method, like this:
$warehouses = WarehousePivotCategory::with(['warehouse' => function($q) use ($title) {
$q->where('title', 'like', '%' . $title . '%')->get(['id', 'title']); },'WarehouseCategory'])->get();
That is wrong. You don't need to use hasone while you have created pivot.You need to use BelongsToMany
class warehouse extends Model{
public function ware_cat(){
return $this->BelongsToMany('App\Models\WarehouseCategory');
}
public function getWarehouse(){
$this->with('ware_cat')->get();
}
}
Pivot table will fetch it so in warehouse model you will get its category and in category model you will get the warehouse same way visa-versa.

Resources