The following is part of my query for querying data between two dates:
->whereDate('fixture_date', '>=', Carbon::now()->subDays($pastDays))
->whereDate('fixture_date', '<=', Carbon::now()->addDays($futureDays))
->when(request('search'), function ($query) {
$query->orWhere('fixture_hometeam_name', 'LIKE', '%' . request('search') . '%')
->orWhere('fixture_awayteam_name', 'LIKE', '%' . request('search') . '%');
})
When request('search') is empty, I am getting the expected results but when not, the whereDate queries are not working.
How should this be modified to give the correct results?
Add another layer to add parenthesis around the orWhere of the search.
->whereDate('fixture_date', '>=', Carbon::now()->subDays($pastDays))
->whereDate('fixture_date', '<=', Carbon::now()->addDays($futureDays))
->when(request('search'), function ($query) {
$query->where(function($subQuery) {
$subQuery->orWhere('fixture_hometeam_name', 'LIKE', '%' . request('search') . '%')
->orWhere('fixture_awayteam_name', 'LIKE', '%' . request('search') . '%');
})
})
You can use whereBetween instead of two whereDate.
->whereBetween('fixture_date', [
now()->subDays($pastDays)->startOfDay(), now()->addDays($futureDays)->endOfDay()
])->when($request->search, function ($query, $search) {
return $query->where(function ($query) use ($search) {
$query->where('fixture_hometeam_name', 'like', "%{$search}%")
->orWhere('fixture_awayteam_name', 'like', "%{$search}%");
});
https://laravel.com/docs/8.x/queries#logical-grouping
You should always group orWhere calls in order to avoid unexpected behavior when global scopes are applied.
Related
public function getListStaff(string $searchString = '')
{
return Staff::with(['citizen_identification' => function ($query) {
$query->where('full_name', 'like', '%' . $searchString . '%');
}])
->where('phone', 'like', '%' . $searchString . '%')
->orWhere('email', 'like', '%' . $searchString . '%')
->paginate(2);
}
I use Repository in project livewire of me, i newbie use livewire, when i code method getListStaff is faulty, i try fix, but not success, please help me fix... Thanhks bros
Because I wrong syntax or visual code error or so ???
It seems like you have missed use statement for searchstring.
In any case, based from you question its not clear what is not working.
return Staff::with([
'citizen_identification' => function ($query) use ($searchString) {
$query->where('full_name', 'like', '%'.$searchString.'%');
},
])
->where('phone', 'like', '%'.$searchString.'%')
->orWhere('email', 'like', '%'.$searchString.'%')
->paginate(2);
I have searched a lot for this but couldn't find related issues.
I have an Eloquent query in my app that is the following:
$cidades = Cidade::when($pesquisa, function ($q) use ($pesquisa) {
return $q->where('nome', 'like', '%' . $pesquisa . '%')
->orWhere('iso_ddd', 'like', '%' . $pesquisa . '%');
})
->when($estado, function ($q) use ($estado) {
return $q->where('estado_id', $estado);
})
->sortable('nome')
->simplePaginate($request->input('p'));
As you can see, I have two 'when' methods to filter the content. My intention is to check wheter each of them are active and filter the query accordingly. But the query above only works if only one of them is active at once. If $pesquisa is set, then it filters the content using the function, but ignores the following 'when' (objects of any $estado show up). If $pesquisa is not set but $estado is, then it correctly runs only the $estado's 'when'.
I could get it to run as excpected by copying $estado's 'when' inside $pesquisa's 'when', like this:
$cidades = Cidade::when($pesquisa, function ($q) use ($pesquisa, $estado) {
return $q->where('nome', 'like', '%' . $pesquisa . '%')
->when($estado, function ($q) use ($estado) {
return $q->where('estado_id', $estado);
})
->orWhere('iso_ddd', 'like', '%' . $pesquisa . '%');
})
->when($estado, function ($q) use ($estado) {
return $q->where('estado_id', $estado);
})
->sortable('nome')
->simplePaginate($request->input('p'));
But I find it a bit redundant. Is there any other way to query it?
I suspect the issue is the fact that there's an or involved. This is what you get when both are set:
SELECT * FROM cidades WHERE nom LIKE ? OR iso_ddd LIKE ? AND estado_id = ?
Due to AND having higher associativity to OR this would get all records where nom LIKE ? OR (iso_ddd LIKE ? AND estado_id = ?) which is not exactly what you seem to want.
You can try:
$cidades = Cidade::when($pesquisa, function ($q) use ($pesquisa) {
return $q->where(function ($q) use ($pesquisa) {
$q->where('nome', 'like', '%' . $pesquisa . '%')
->orWhere('iso_ddd', 'like', '%' . $pesquisa . '%');
});
})->when($estado, function ($q) use ($estado) {
return $q->where('estado_id', $estado);
})
->sortable('nome')
->simplePaginate($request->input('p'));
this should put parentheses around (nom = ? or iso_ddd = ?) to ensure the conditions are grouped correctly.
You can set the when parameter value to true. Then just check the condition inside the when
$cidades = Cidade::when(true, function ($q) use ($pesquisa, $estado) {
if ($estado) {
return $q->where('estado_id', $estado);
}
return $q->where('nome', 'like', '%' . $pesquisa . '%')
->orWhere('iso_ddd', 'like', '%' . $pesquisa . '%');
})
->sortable('nome')
->simplePaginate($request->input('p'));
By looking at the query log (DB::getQueryLog()) I found out that my problem was related to associativity.
The solution was to put the $estado's when before the $pequisa's when. That solved it.
DB::enableQueryLog();
$cidades = Cidade::when($estado, function ($e) use ($estado) {
return $e->where('estado_id', $estado);
})
->when($pesquisa, function ($q) use ($pesquisa, $estado) {
return $q->where('nome', 'like', '%' . $pesquisa . '%')
->orWhere('iso_ddd', 'like', '%' . $pesquisa . '%');
})
->sortable('nome')
->simplePaginate($request->input('p'));
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);
}
I have search form to get information from table named books.
Right now i'm using this controller
public function search(Request $request)
{
$keyword = $request->input('keyword');
$query = Book::where('judul', 'LIKE', '%' . $keyword . '%');
$book_list = $query->paginate(5);
$pagination = $book_list->appends($request->except('page'));
$total_book = $book_list->total();
return view('dashboards.index', compact('book_list', 'keyword', 'pagination', 'total_book'));
}
The problem is the data that i get from the request only available for judul. it just show empty result if the input keyword search addressed to search writter or publisher
I want the search form able to get data from other columns named writters and publisher
Is there any method to get data from multiple column?
You can use orwhere to fullfill this, like this
Book::where(function ($query) use($keyword) {
$query->where('judul', 'like', '%' . $keyword . '%')
->orWhere('writters', 'like', '%' . $keyword . '%');
})
->get();
I hope it helps you.
You can execute conditional queries in many ways.
1. You can use when():
Book::when($keyword, function ($q) use ($keyword) {
return $q->where('judul', 'LIKE', '%' . $keyword . '%');;
})
->get();
2. Use the where closure:
Book::where(function($q) use ($keyword, $request) {
if ($request) {
$q->where('judul', 'LIKE', '%' . $keyword . '%');
}
})
->get();
3. Do this:
$books = Book::query();
if ($request) {
$books = $books->where('judul', 'LIKE', '%' . $keyword . '%');
}
$books = $books->get();
Laravel 4 - advanced Where
I'm trying to retrieve Posts that have a $keyword like a certain Companion and besides that I want to retrieve the Posts the have a linking title or content as the $keyword.
But when I try to use a where or whereIn inside a whereHas the query doesn't take these into account. When the state is 0 (not visible) or not inside the category 1 the Post item should not get selected.
$companion_id = Companion::where('name', 'LIKE', '%' . $keyword . '%' )->lists('id');
The code block below has to do two things:
Search for Post items with a title or content like the $keyword
and search for Post items that have Companions like the $keyword
code:
$results = Post::whereHas('companions', function($query) use($companion_id)
{
$query->whereIn('companions.id', $companion_id)
->where('state', '=', 1)
->whereIn('category_id', array(1));
})
->whereIn('category_id', array(1))
->orwhere('title', 'LIKE', '%' . $keyword . '%' )
->orWhere('content', 'LIKE', '%' . $keyword . '%' )
->where('state', '=', '1')
->orderBy('menu_order', 'desc')
->get();
The code above retrieves data succesfully except for the where and whereIn parts inside the whereHas.
Who can help me out?
wrap your orWhere clauses in (..)
you don't need where and whereIn in the whereHas closure, since it queries companions table
you don't need whereIn for category_id, unless you want to pass multiple ids there
.
$results = Post::whereHas('companions', function($query) use($companion_id)
{
$query->whereIn('companions.id', $companion_id);
})
->whereIn('category_id', array(1)) // why not where(..) ?
->where(function ($q) use ($keyword) {
$q->where('title', 'LIKE', '%' . $keyword . '%' )
->orWhere('content', 'LIKE', '%' . $keyword . '%' );
})
->where('state', '=', '1')
->orderBy('menu_order', 'desc')
->get();
Thanks to Jarek Tkaczyk.
His answer was almost correct. All I had to do was wrap the where inside a orWhere. Now I get the Posts that has a Companion like the $keyword and I get the Posts that has the $keyword inside the content or title.
$results = Post::whereHas('companions', function($query) use($companion_id)
{
$query->whereIn('companions.id', $companion_id)
->where('state', '=', '1');
})
->orWhere( function($q) use ( $keyword ) {
$q->where('title', 'LIKE', '%' . $keyword . '%' )
->orWhere('content', 'LIKE', '%' . $keyword . '%' );
})
->whereIn('category_id', array(1, 3))
->where('state', '=', '1')
->orderBy('menu_order', 'desc')
->get();