Laravel break up paginated eloquent query - laravel

I currently have:
$comments = $this->post->comments()
->where('comment', 'like', "%{$search}%")
->paginate(50);
But I'd like to do something like the below, as I have multiple filters that I'm going to apply:
$comments = $this->post->comments();
if(condition)
{
$comments->where('comment', 'like', "%{$search}%");
}
$comments->paginate();
But the code above doesn't work as I then get errors on things like $comments->links() for pagination links in the view, indicating that this doesn't work.

What you can try is something like this, I don't know what Laravel version you are using, also I don't know the structure you have of your models, but here's the documentation about this example:
$conditions = 1;
$comments = Post::with('comments')
->whereHas('comments', function ($query) use ($conditions){
// pass your conditions
if(!$conditions){
$query->where('comment', 'like', "%%")
}
// more conditions, etc
$query->where('comment_id', 'like', '%%');
})->paginate(50);

It was missing $comment = in front of the query clauses:
$comments = $this->post->comments();
if(condition)
{
$comments = $comments->where('comment', 'like', "%{$search}%");
}
$comments = $comments->paginate();

Related

Laravel whereHas Returns all records

I have have 3 tables in my projects they are:
products(can have Multiple Variants)
variants (belongsto product)
product_attributes (this have product_id,attribute_id,value_id)
I want to filter variants from a product by value ids thats comes from form request as example (1,2,6)
I have tried like this:
$poruduct_id = $request->product_id;
$value_ids = $request->value_ids;
$searched_variants = Variant::whereHas('product.attributeValues', function ($query) use ($value_ids, $product_id) {
$query->whereIn('value_id', [$value_ids]);
})->where('product_id', $product_id)->get();
dd($searched_variants);
But the problem is the query returns all records from the product. What is the solution to filter exactly the values that the product Variants have?
Thank you.
-UPDATED-
I have tried like this but nothing changed
$searched_variants = Variant::select('product_id')->whereHas('product.attributeValues', function ($query) use ($value_ids, $product_id) {
$query->whereIn('value_id', [$value_ids]);
})->groupBy('product_id')
->havingRaw('COUNT(*) = ?', [count((array) $value_ids)])
->get();
-**FİNALLY SOLUTİON**-
I made it like this : I get the value code that is in for example Large the code is L
get all the codes to controller and executed this query ı hope this helps someone
1.$value_codes=$request->value_codes;
2.$value_codes_array=explode(',',$value_codes);
3.$product_id=$request->product_id;
4.$searchValues = preg_split('/,/', $value_codes_array, -1, PREG_SPLIT_NO_EMPTY);
$searchValues = preg_split('/,/', $value_idss, -1, PREG_SPLIT_NO_EMPTY);
$variants= Variant::where(function ($q) use ($searchValues) {
foreach ($searchValues as $value) {
$q->orWhere('sku', 'like', "%-{$value}")
->orWhere('sku', 'like', "%-{$value}-%")
->orWhere('sku', 'like', "{$value}-%");
}
})->where('product_id',$product_id)->get();
dd($variants);
If you have n variants to one product, you query should be like:
Product Model
public function variants: HasMany relationships
//usage
$produtc->variants->and here the query function
You need to use it in this way, it should work:
$productId = $request->product_id;
$valueIds = $request->value_ids;
$searchedVariants = Variant::whereHas('product.attributeValues', function ($query) use ($valueIds) {
$query->distinct()->whereIn('value_id', $valueIds);
}, '=', count($valueIds))->where('product_id', $productId)->get();

use like on laravel can't display date search

i want to search data based nama_kegiatan or tanggal_kegiatan where these two name form my table field, this code from my controller :
public function search(Request $request){
$cari = $request->search;
$caritanggal = date($request->datekeg);
$infokeg = Infokeg::where(function ($query) use ($cari) {
$query->where('nama_kegiatan','like',"%$cari%")->get();
})->orWhere(function($query) use ($caritanggal) {
$query->where('tanggal_kegiatan', $caritanggal)->get();;
})->paginate(10);
return view('infokeg/infokeg', ['infokeg' => $infokeg]);
}
when i am using like on nama_kegiatan, tanggal_kegiatan didnt work and just display all data, but when i delete like from nama_kegiatan, its work, but i cant search nama_kegiatan using like, so how to solve it ?
Maybe you can try to get() all the result after the query? Somethings like
$infokeg = Infokeg::where('name_kegiatan','LIKE','%'.$cari.'%')->orWhere('tanggal_kegiatan',$caritanggal)->get();
IMO the get() and paginate() cannot be use at the same time if I have not get it wrong. If you need to paginate after all the result, you can do create Paginator manually. Maybe this link can help you. Hope this will help you and please correct me if anything wrong. Thanks!
If you want to see what is run in the database use dd(DB::getQueryLog()) after query to see what queries exactly were run.
$infokeg = Infokeg::where('nama_kegiatan','like', "%" . $cari ."%")
->orWhere(function($query) use ($caritanggal) {
$query->where('tanggal_kegiatan', $caritanggal);
})->paginate(10);
just make it into if condition
public function search(Request $request)
{
$cari = $request->search;
$caritanggal = $request->datekeg;
if (isset($cari)) {
$infokeg = Infokeg::where('nama_kegiatan', 'like', '%'.$cari.'%')
->paginate(5);
}elseif (isset($caritanggal)) {
$infokeg = Infokeg::where('tanggal_kegiatan', 'like', '%'.$caritanggal.'%')
->paginate(5);
}elseif (isset($cari)&&isset($caritanggal)) {
$infokeg = Infokeg::where('nama_kegiatan', 'like', '%'.$cari.'%')
->orWhere('tanggal_kegiatan', 'like', '%'.$caritanggal.'%')
->paginate(5);
}
return view('/admin/infokeg/infokeg', ['infokeg' => $infokeg]);
}

Query relationship inside the relationship in Laravel Eloquent

I am trying to get the news of a writer according to date passed. I have written function so far:
public static function getNewsByAuthorByDate($id, $year, $limit = 1){
return User::where('id', $id)->has('news')
->with(['news' => function($q) use(&$limit, &$year) {
$q->where('created_at', 'like', '%' . $year . '%')->latest()->limit($limit);
}])
->first();
}
But the news[] is null. Is it possible to get writer news according to date or do I have to try another way?
you can use whereYear
public static function getNewsByAuthorByDate($id, $year, $limit = 1){
return User::where('id', $id)->has('news')
->with(['news' => function($q) use(&$limit, &$year) {
$q->whereYear('created_at',$year)->latest()->limit($limit);
}])
->first();
}
and to use limit with eager loading you should use the package eloquent-eager-limit
According to the documentation:
The limit and take query builder methods may not be used when constraining eager loads.
Also, You don't need to use has method, the news would be empty if the user has no news:
return User::with(['news' => function($q) use($year) {
$q->whereYear('created_at', $year)->latest();
}])
->find($id);

Eloquent where condition AND ( condition OR condition OR condition )

Can somebody tell me what am I doing wrong?
I want to get all projects with status 0 and if any of data matches in eloquent.
My code is like this
public function search(Request $request){
if($request->has('q')){
$search_query = $request->input('q');
$projects = Project::where(['status' => '0'])->get();
$projects = $projects->where(function($query) use ($search_query) {
$query->where('title','LIKE','%'.$search_query.'%')
->orWhere('shortDescription','LIKE','%'.$search_query.'%')
->orWhere('longDescription','LIKE','%'.$search_query.'%')
->orWhere('tags','LIKE','%'.$search_query.'%')
->orWhere('projectLink','LIKE','%'.$search_query.'%');
});
$projects->get();
dd($projects);
}
}
And I am getting this error
ErrorException
explode() expects parameter 2 to be string, object given
I solved the problem but changed the code a little bit... If you like, take it! I tested and it's working.
if($request->has('q')){
// Your $request->q Value
$term = $request->q;
$projects = DB::table('tbl_projects')->where('status', '=', 0)
->where(function ($query) use ($term) {
$query->where('title', 'LIKE', '%'.$term.'%')
->orWhere('shortDescription', 'LIKE', '%'.$term.'%')
->orWhere('longDescription', 'LIKE', '%'.$term.'%')
->orWhere('tags', 'LIKE', '%'.$term.'%')
->orWhere('projectLink', 'LIKE', '%'.$term.'%');
})
->get();
//dd($projects);
}
Raw query is:
select * from `tbl_projects` where `status` = 0 and (`title` LIKE %bla bla% or `shortDescription` LIKE %bla bla% or `longDescription` LIKE %bla bla% or `tags` LIKE %bla bla% or `projectLink` LIKE %bla bla%))
Regards!
Your error is
$projects = Project::where(['status' => '0'])->get();
(['status' => '0']) Where clause params required is different. You must use ('status', '0') or ('status', '=', '0')
When you use ->get(), you have a Collection or EloquentCollection object. You need a QueryBuilder
Try to implement a better programation logic.
A better implementation is
public function search(Request $request){
if($request->has('q')){
// Add array with field coincidences target. Is better if this array is a const static field in the Project model
$searchFields = ['title', 'shortDescription', 'longDescription', 'tags', 'projectLink' ];
// Now you can add 100 fields for search coincidences easily
$search_query = $request->input('q');
$projects = Project::where('status', '0');
foreach($searchFields as $searchField){
if ($searchField == 'title'){
$projects = $projects->where($searchField,'LIKE',"%$search_query%");
continue;
}
$projects = $projects->orWhere($searchField,'LIKE',"%$search_query%");
}
$projects = $projects->get();
dd($projects);
}
}

or where clause - Laravel eloquent

I have this query:
if($keyword){
array_push($where, ['name_en', 'LIKE', '%'.$keyword.'%']);
}
The problem is that I have and name_fr column and I need to use OR clause - array_push($where, ['name_fr', 'LIKE', '%'.$keyword.'%']).
I can't use ->orWhere, because I have many dynamic search fields - they may exists or not.
For the example:
if($fromPrice){
array_push($where, ['price', '>=', $fromPrice]);
}
if($toPrice){
array_push($where, ['price', '<=', $toPrice]);
}
And the query is:
$cars= Property::with(array(
'photos'=>function($query){
$query->select(['car_id', 'name']);
}
))->where($where)->paginate(10);
I need to select WHERE name_en LIKE %val% OR name_fr LIKE %val% with another queries.
Is there a way to use somehow where, 'OR' and LIKE in the above way including another values from $where array ?
to achieve that a suggest you to divide your query as below and don't put your keyword condition within $where array:
$query = Property::with(array(
'photos'=>function($query){
$query->select(['car_id', 'name']);
}
))->where($where);
if($keyword){
$query = $query->where(function ($query) use ($keyword) {
$query->where('name_fr', 'like', $keyword)
->orWhere('name_en', 'like', $keyword);
});
}
$cars = $query->paginate(10);
You can also go with
$propertyQuery = Property::query();
if($keyword){
$propertyQuery->where(function($query) use ($keyword){
$query->where('name_fr', 'LIKE', '%'.$keyword.'%')->orWhere('name_en', 'LIKE', '%'.$keyword.'%');
});
}
$cars = $propertyQuery->paginate(10);

Resources