PHP Laravel search multiple tables with multiple keywords from multiple inputs - php

I have two tables in db, "deals" and "deals_meta" connected between them with a foreign key.
In the "deals" table i have general information about a deal like, title, description, category etc., and in the "deals_meta" i have other specific details like, location, number of bedrooms, price, booking date and so on.
I have a form with multiple fields, title, details, booking date, price range and so on.
My problem is that i can't retrieve from db the deals based on the search query.
The code that i use to retrieve the queries looks like this:
$deals = Deals::where('deals_providers', $provider)->where('deal_types', $dealType)->with('meta')
->where(function ($query) use ($terms, $dealType) {
$query->whereHas('meta', function ($query) use ($terms, $dealType) {
$search = $query->where('deal_type', 'like', '%' . $dealType . '%');
if ($terms['location']) {
$search = $query->orWhere('location', 'like', '%' . $terms['location'] . '%');
}
if ($terms['price_from']) {
$search = $query->orWhere('price', '>', '%' . $terms['price_from'] . '%');
}
if ($terms['price_to']) {
$search = $query->orWhere('price', '<', '%' . $terms['price_to'] . '%');
}
if ($terms['departs_from']) {
$search = $query->orWhere('departs_from', 'like', '%' . $terms['departs_from'] . '%');
}
if ($terms['duration']) {
$search = $query->orWhere('duration', 'like', '%' . $terms['duration'] . '%');
}
if ($terms['available_start']) {
$search = $query->orWHere('available_start', 'like', '%' . $terms['available_start'] . '%');
}
if ($terms['available_end']) {
$search = $query->orWhere('available_end', 'like', '%' . $terms['available_end'] . '%');
}
return $search;
});
if ($terms['title']) {
$query->orWhere('title', 'like', '%' . $terms['title'] . '%');
}
if ($terms['details']) {
$query->orWhere('details', 'like', '%' . $terms['details'], '%');
}
})->get();
Debug::data($deals);
If i search for title or details, it returns only the deals that have that title or contains that details but if i search for location or any other meta related term, it returns all the deals results from the db.
What i'm doing wrong or how can i search corectly?
Thank you!

Solved!
This is the code that works for my case!
$deals = Deals::where('deals_providers', $provider)->where('deal_types', $dealType)->with('meta')
->where(function ($query) use ($terms, $dealType) {
$query->whereHas('meta', function ($query) use ($terms, $dealType) {
if ($terms['location']) {
$query->where('location', 'like', '%' . $terms['location'] . '%');
}
if ($terms['price_from'] && $terms['price_to']) {
$query->whereBetween('price', [$terms['price_from'], $terms['price_to']]);
}
if ($terms['departs_from']) {
$query->where('departs_from', 'like', '%' . $terms['departs_from'] . '%');
}
if ($terms['duration']) {
$query->where('duration', 'like', '%' . $terms['duration'] . '%');
}
if ($terms['available_start']) {
$query->where('available_start', 'like', '%' . $terms['available_start'] . '%');
}
if ($terms['available_end']) {
$query->where('available_end', 'like', '%' . $terms['available_end'] . '%');
}
});
if ($terms['title']) {
$query->orWhere('title', 'like', '%' . $terms['title'] . '%');
}
if ($terms['details']) {
$query->orWhere('details', 'like', '%' . $terms['details'], '%');
}
})->get();
Debug::data($deals);

Related

Multiple when() clauses in Laravel

I have a request('name') and request('surname') that I need to search respectively in 2 columns with this logic:
If request('name'):
request('name') in column name_kanki or in column name_romaji
And if request('surname'):
request('surname') in column surname_kanki or in column surname_romaji.
I only could write the following code to perform the search:
->when($nameSearch, function ($query, $nameSearch) {
return $query->where('name', 'LIKE', '%' . $nameSearch . '%')
->orWhere('name_kanji', 'LIKE', '%' . $nameSearch . '%');
})
->when($surnameSearch, function ($query, $surnameSearch) {
return $query->where('surname', 'LIKE', '%' . $surnameSearch . '%')
->orWhere('surname_kanji', 'LIKE', '%' . $surnameSearch . '%');
})
Now the problem is that the first when() and the second when() seem to be connected to each other by OR logic, while I need AND logic.
At present when I insert for example only the name field, the search works fine, but if I insert both name and surname I get the results added to each other (OR logic).
How can I change this relationship to an AND logic (2 filters) that works if both name and surname fields have been compiled by the user?
Thanks in advance.
Hope this will help you to achieve you AND condition result. instead of when I try with where method.
->where(function ($query) use($nameSearch, $surnameSearch) {
if(isset($nameSearch)){
return $query->where('name', 'LIKE', '%' . $nameSearch .
'%')
->orWhere('name_kanji', 'LIKE', '%' . $nameSearch .
'%');
}else{
return $query->where('surname', 'LIKE', '%' .
$surnameSearch . '%')->orWhere('surname_kanji',
'LIKE', '%' . $surnameSearch . '%');
}
})

Make a query in two different tables and two different columns with Eloquent

I have a database with 3 tables.
Artists, Albums and Songs. They all have their name columns.
I have a query that can include the artist and the name of the Album or the artist and the name of any of the Sounds within the Album.
How can I get all the Albums that match the search?
I have tried the following
$album->where('name', 'like', '%' . $name . '%')
->orWhere('name', 'sounds like', '%' . $name . '%')
->orWhereHas('artist', function ($songArtist) use ($name) {
return $songArtist->where('name', 'like', '%' . $name . '%');
})
->orWhereHas('artist', function ($songArtist) use ($name) {
return $songArtist->where('name', 'sounds like', '%' . $name . '%');
})
->orWhereHas('songs.artists', function ($songArtist) use ($name) {
return $songArtist->where('name', 'like', '%' . $name . '%');
})
->orWhereHas('songs.artists', function ($songArtist) use ($name) {
return $songArtist->where('name', 'sounds like', '%' . $name . '%');
});
However, this only works for me when searching by name only. If I include the artist name it doesn't give any result for obvious reasons.
I would like to obtain all albums that include the artist and name if a query is made

How to fetch data from two tables using ORM in LIKE search using Laravel

This is my controller code:
public function searchUser(Request $request)
{
$pram = $request->name;
$data['users'] = User::whereHas('userBasicInfo', function ($query) use ($pram) {
$query->where('first_name', 'like', '%' . $pram . '%')
->orWhere('middle_name', 'like', '%' . $pram . '%')
->orWhere('last_name', 'like', '%' . $pram . '%');
})->with(['userBasicInfo' => function ($query) use ($pram) {
$query->where('first_name', 'like', '%' . $pram . '%')
->orWhere('middle_name', 'like', '%' . $pram . '%')
->orWhere('last_name', 'like', '%' . $pram . '%');
}])->get();
return $data;
}
I have relationship of user with userBasicInfo; I can search with first_name, middle_name and last_name and my request parameter is name.
Now I want to search with user email and there will be one more request parameter which is email and email is in users table.
How I can search with user email as well?
Try like
$data['users'] = User::with('userBasicInfo')
->where('email', 'like', '%' . $pram . '%') //this is from use table
->orWhereHas('userBasicInfo', function($query) use($pram) {
//search in basic info table
$query->where('first_name', 'like', '%' . $pram . '%')
->orWhere('middle_name', 'like', '%' . $pram . '%')
->orWhere('last_name', 'like', '%' . $pram . '%');
})
->get();
You don't need to send different value from the search form. A single value can be used as the search value.

Where on multiple whereHas

I need to be able to run a where query on a model and multiple of its relations at once. At the moment I am doing it like this, for a single relation
$users = $users->whereHas('contacts', function ($query) use ($request) {
$query->where('name', 'like', '%' . $request->input('filters_search') . '%')
->orWhere('contact_name', 'like', '%' . $request->input('filters_search') . '%');
);
So this searches my user.name and contact.name fields for the search input, but I need to be able to search multiple relations, not just contacts. Something like this
$users = $users->whereHas(['contacts','photos','status'], function ($query) use ($request) {
$query->where('name', 'like', '%' . $request->input('filters_search') . '%')
->orWhere('contact_name', 'like', '%' . $request->input('filters_search') . '%');
);
So that I can search through the user, contacts, photos and status tables/relations for the search input.
What is the cleanest/best way to achieve this?
If you did happen to be searching the same columns in all of your tables, you could extract the closure to a variable:
$closure = function ($query) use ($request) {
$query->where('name', 'like', '%' . $request->input('filters_search') . '%')
->orWhere('contact_name', 'like', '%' . $request->input('filters_search') . '%');
}
But you'd still have to independently query each relationship:
$users->whereHas('contacts', $closure)
->orWhereHas('photos', $closure)
->orWhereHas('status', $closure);
You should try this:
$users = $users->whereHas('photos','status', function($query) {
$query->where('name', 'like', '%' . $request->input('filters_search') . '%');
});
$users = $users->whereHas('contacts', function($query) use ($request) {
$query->where('contact_name', 'like', '%' . $request->input('filters_search') . '%');
});
OR you should try below way:
User::where('name', 'like', '%' . $request->input('filters_search') . '%')
->whereHas('contacts', function($query) use ($request) {
$query->where('contact_name', 'like', '%' . $request->input('filters_search') . '%');
})
->get();

Laravel query build not working, why?

Could someone explain me the reason why is this query not working? I am trying to create a query - where clients name, email or phone match the necessary criteria. However, it seems to work only with one criteria (name or email or phone), not with several ones. That way, I do not get the results needed and I am left with non- filtered list.
Using Laravel 4.1
$q = new Contract;
$q = $q->with(array('lsct' => function($q) {
return $q->select(array('id', 'code'));
}, 'client' => function($q) {
return $q->select(array('id', 'name', 'phone', 'email'));
}));
if(Input::has('search')) {
$criterion = Input::get('search');
$q = $q->where(function($q) use ($criterion) {
$q->where('uid', 'like', '%' . $criterion . '%')->orWhere('car_number', 'like', '%' . $criterion . '%');
})->orWhereHas('lsct', function($q) use($criterion) {
$q->where('code', 'like', '%' . $criterion . '%');
})->orWhereHas('client', function($q) use($criterion) {
$q->where('name', 'like', '%' . $criterion . '%');
// When i try to add condition below, this 'orWhereHas' not working at all
// ->orWhere('phone', 'like', '%' . $criterion . '%')
//->orWhere('latakko_id', 'like', '%' . $criterion . '%');
});
}
Have you tried installing debugbar to show you exactly what your application is querying?
Here is the link for Laravel 4
This might give you some clues if you can actually see what is being queried.

Categories