searching on name instead of id on sql - laravel

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

Related

How to get foreign key data in main field Laravel

I have a problem connecting to the data for searching the customer's name because I only identify the id as a foreign key. How can I get data from the customer table? I tried using a join table but no got no result.
public function render()
{
$search = $this->searchTerm;
$data = Order::with('customer')->where('user_id', Auth::id())
->where(function ($query) use ($search) {
$query->where('customer_id', 'like', '%' . $search . '%') // <- this field linked in customers table to get name of customer
->orWhere('orderNumber', 'like', '%' . $search . '%');
})->orderBy('id', $this->sortDirection)->paginate(9);
return view('livewire.dashboard.orders.list-order', compact('data'));
}
If I am right I think you are trying to search for customer name through customer relationship
You can do it like this:
$search = $this->searchTerm;
$data = Order::where('user_id', Auth::id())->with(['customer' =>
function($query) use($search){
$query->where('name','like', '%' . $search . '%')
->orWhere('orderNumber', 'like', '%' . $search . '%');
}])->orderBy('id', $this->sortDirection)->paginate(9);

Laravel eloquent real time search filtering

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

Laravel eloquent complex search query question

Have been trying different approaches to perform a search query with Eloquent on multiple and nested many-to-many and hasmany relationships but having trouble finding the solution.
To simplify below the part of the models where I want to perform the search using 'model', 'LIKE', '%' . $request->name . '%'.
The models
class Company extends Model {
// the class properties, dates, etc...
public function offices(){
return $this belongsToMany(Office::class);
}
}
class Office extends Model {
// the class properties, dates, etc...
public function companies(){
return $this belongsToMany(Company::class);
}
public function addresses(){
return $this belongsToMany(Address::class);
}
}
class Address extends Model {
// the class properties, dates, etc...
public function offices(){
return $this belongsToMany(Office::class);
}
public function services(){
return $this belongsToMany(Service::class);
}
public function countries(){
return $this belongsToMany(Country::class);
}
}
class Service extends Model {
// the class properties, dates, etc...
public function addresses(){
return $this belongsToMany(Address::class);
}
}
class Country extends Model {
// the class properties, dates, etc...
public function addresses(){
return $this belongsToMany(Address::class);
}
}
The goal to to search on the different models based on the main model which is Company. In pseudo code would be something like the following:
Find in Company where name like $request->name
Or where Company website like $request->name
Or where Office office_name $request->name
Or where Address street $request->name
Or where Address country.name $request->name
Or where Service addresses.service.name $request->name
A Company has many Office
An Office has many Address
An Address has a Country and
An Address has many Services.
In all of them, and to simplify (i'll probably be able to extrapolate and work o other fields for each model, I'll be using the name column. Eg. company name, office name, address name, service name country name.
What I have now is the following which is not performing the search as I need:
public function search(Request $request)
{
$data = Company::Active()->with('offices', 'addresses', 'offices.addresses')
->where('company_name', 'LIKE', '%' . $request->name . '%')
->orWhere('company_short_description', 'LIKE', '%' . $request->name . '%')
->orWhere('company_long_description', 'LIKE', '%' . $request->name . '%')
->orWhere('company_website', 'LIKE', '%' . $request->name . '%')
->whereHas('offices', function ($query) use ($request) {
$query->where('name', 'LIKE', '%' . $request->name . '%');
})
->whereHas('offices.addresses', function ($query) use($request){
$query->where('name', 'LIKE', '%' . $request->name . '%')
->orWhere('address_city', 'LIKE', '%' . $request->name . '%');
})
->orderBy('company_name')
->paginate(20);
return response()->json($data, 200);
}
Thank you in advance for any help or tips on the better solution to perform this broad (complex) search query with Eloquent.
I think I could manage the query. Not sure if the best approach or it might need some optimization, but I could get at least the most approximate result sets from the below query. Suggestions on improvements are welcome :)
public function search(Request $request)
{
$data = Company::Active()->with('offices', 'addresses', 'offices.addresses')
->where('company_name', 'LIKE', '%' . $request->name . '%')
->orWhere('company_short_description', 'LIKE', '%' . $request->name . '%')
->orWhere('company_long_description', 'LIKE', '%' . $request->name . '%')
->orWhere('company_website', 'LIKE', '%' . $request->name . '%')
->orWhereHas('offices', function ($query) use ($request) {
$query->where('name', 'LIKE', '%' . $request->name . '%');
})
->orWhereHas('offices.addresses', function ($query) use($request){
$query->where('name', 'LIKE', '%' . $request->name . '%')
->orWhere('address_city', 'LIKE', '%' . $request->name . '%');
})
->orWhereHas('offices.addresses.services', function ($query) use($request){
$query->where('name', 'LIKE', '%' . $request->name . '%');
})
->orderBy('company_name')
->paginate(20);
return response()->json($data, 200);
}

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

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