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 . '%');
}
})
Related
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.
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();
My issue has three tables: "comments", "users" & "company_contacts"
The "comments" table has two columns: "company_contact (INT)" & "company_contact_kind (String)"
comments.company_contact is either assigned to users.id or company_contacts.id based upon either if comments.company_contact_kind = 'contact' or if comments.company_contact_kind = 'user'
Here is my query:
$data['comments'] = Comment::join('users', 'comments.creator_id', '=', 'users.id')
->join('users AS user_contacts', 'comments.company_contact', '=', 'user_contacts.id')
->join('company_contacts', 'company_contacts.id', '=', 'comments.company_contact')
->where('comments.commentable_type', $request->type)
->where('comments.commentable_id', $request->company_id)
->where(function($query) use ($request){
$query->orWhere('body', 'LIKE', '%' . $request->q . '%')
->orWhere('users.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('users.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('user_contacts.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('user_contacts.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('company_contacts.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('company_contacts.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('comments.contact_type', 'LIKE', '%' . $request->q . '%')
->orWhere('tags', 'LIKE', '%' . $request->q . '%');
})
->orderBy('comments.created_at', 'DESC')
->select('comments.*')
->get();
My Issue:
When searching for a specific Comment Contact, because I reference both users and company contacts within my query and both equal comments.company_contact, if I search for either the first or last name of company_contacts.id, it'll return results with users.id as the comments.company_contact because comments.company_contact references both users and company_contacts.
Is there a way to set a condition within the query for something more intuitive?
Solved:
Thanks to the answer proposed by #cmerriman, I was able to tweak the answer and solve it by the following query:
$data['comments'] = Comment::join('users', 'comments.creator_id', '=', 'users.id')
->leftJoin('users AS user_contacts', function ($join) {
$join->where('comments.company_contact_kind', '=', 'user')
->on('comments.company_contact', '=','user_contacts.id');
})
->leftJoin('company_contacts', function ($join) {
$join->where('comments.company_contact_kind', '=', 'contact')
->on('comments.company_contact', '=','company_contacts.id');
})
->where('comments.commentable_type', $request->type)
->where('comments.commentable_id', $request->company_id)
->where(function($query) use ($request){
$query->orWhere('body', 'LIKE', '%' . $request->q . '%')
->orWhere('users.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('users.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('user_contacts.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('user_contacts.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('company_contacts.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('company_contacts.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('comments.contact_type', 'LIKE', '%' . $request->q . '%')
->orWhere('tags', 'LIKE', '%' . $request->q . '%');
})
->orderBy('comments.created_at', 'DESC')
->select('comments.*')
->get();
I've never used Laravel, but if I am reading the docs correctly, try changing
->join('users AS user_contacts', 'comments.company_contact', '=', 'user_contacts.id')
->join('company_contacts', 'company_contacts.id', '=', 'comments.company_contact')
to
->join('users AS user_contacts', function ($join) {
$join->on('comments.company_contact', '=','user_contacts.id')
->andOn('comments.company_contact_kind, '=', 'user'); } )
->join('companyusers AS user_contacts', function ($join) {
$join->on('comments.company_contact', '=','company_contacts.id')
->andOn('comments.company_contact_kind, '=', 'contact'); } )
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);
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.