Laravel whereDate() not working - laravel

I have used below query to get result with some codition in my controller
$events = Event::whereHas('topic', function ($q) {
$q->where('delete_status', 0);
})
->where('status', 1)
->where('delete_status', 0);
And in my view file i have used this variable thrice to check with Date like below
$events->where('type', '!=', 2)->whereDate('start_date', '>=', \Carbon\Carbon::now())->get()
And
$events->where('type', 2)->whereDate('start_date', '>=', \Carbon\Carbon::now())->get()
And
$events->whereDate('start_date', '<', \Carbon\Carbon::now())->get()
Because i want to get the result based on past date or present date. If i use get in controller query i got error of whereDate() does not exists
So i have used get() method in view file.
I cannot get record from second and third query but I can only get record from 1st query in view file.
Any solution?

$events is an collection which doesn't have whereDate method, what you might be looking for is the filter() to filter your collection in your views. Hence you could do so
$filtered_events =
$events->where('type', 2)
->filter(function ($item) {
return Carbon::parse($item->start_date)->gte(Carbon::today());
});
Reference

Related

How do I search by a table included using with() statement

I am trying to search with a column on a connected table using with. According to laravel the following should work.
$lineItems = Invoice::with(['invoiceHeader' => function ($query) {
$query->where('community_id', '=', 1);
}, 'invoiceLineItems'])
->limit(10)
->get()
->toArray();
However, I don't get anything from the invoiceHeader table and I get all the invoices available. If I take out the function I get the same but with invoiceHeader's table values showing up.
$lineItems = Invoice::with(['invoiceHeader', 'invoiceLineItems'])
->limit(10)
->get()
->toArray();
It seems I might be doing something of a right join where I get all the Invoices but then only the invoiceHeader values when applicable to the foreign key.
Edit:
I put ->toSql(); after the limit() and it shows I only get the following.
"select * from `invoice` limit 10"
You should use whereHas mixing with with:
$lineItems = Invoice::with(['invoiceHeader', 'invoiceLineItems'])
->whereHas('invoiceHeader', function ($query) {
return $query->where('community_id', 1);
})
->limit(10)
->get()
->toArray();

can't use eloquent ::query() on Laravel controller

I'm trying to do a dinamic chained query so im using the query() method, but i'm getting null/empty result I tested it using php artisan tinker and works well but in controller doesn't
$item = Item::query();
$item->where('active', true);
if($request->control_negative_stock){
$item->where('stock', '>', 0);
}
$item->get();
I imported use Illuminate\Database\Eloquent\Builder; class in both model and controller but still doesn't work
First make sure your query satisfies where conditions.Then you should store your conditional query in variable.
$item = Item::query();
$item->where('active', true);
if($request->control_negative_stock){
$item->where('stock', '>', 0);
}
$result=$item->get();
if you dd($result); then you get all data
if you dd($item->get()) then it will show all data if your query satisfies specified condition.
But it fails to return result if you dd($item);
I know this has already been answered and accepted, but I will just share a small tip for better code:
$result = Item::where('active', true)
->when($request->control_negative_stock, function ($query) {
return $query->where('stock', '>', 0);
})
->get();
There is no need to do $item = Item::query(); and then $item->where(....). Also, take advantage of when, so you can avoid ifs and you can directly have a seamless query.

Laravel: Use order by in combination with whereHas

I want to retrieve a collection of data, which is ordered by the start_date of the relation
Basically I want to achieve this, with Laravel Models (the code below works perfectly)
$posts = DB::table('posts')
->leftJoin(
'threads',
'posts.id',
'=',
'threads.postable_id'
)
->where('threads.postable_type', '=', 'App\Post')
->orderBy('threads.start_date')
->paginate($request->input('limit', 2));
So in this case, I'm fetching ALL Posts and those are ordered by the start_date of the thread relation.
Those are not my actual tables but this works perfectly!
Because I'm using https://laravel.com/docs/8.x/eloquent-resources this is not the ideal solution to retrieve sorted data.
So instead I want to use the orderBy clause somewhere here
$posts = Post::whereHas('thread', function ($query) {
$query->where('end_date', '>=', Carbon::now());
});
But I just cannot make this work. I've tried this
$posts = Post::whereHas('thread', function ($query) {
$query->where('end_date', '>=', Carbon::now())
->orderBy('start_date');
});
and I also appended this to the actual relation:
public function thread(): MorphOne
{
return $this->morphOne('App\Thread', 'postable')->orderBy('start_date');
}
If you look at your code:
$posts = Post::whereHas('thread', function ($query) {
$query->where('end_date', '>=', Carbon::now())
->orderBy('start_date');
});
the whereHas will only return Post associate with a thread which the function return true.
Try this:
$posts = Post::with('thread')->has('thread')->orderBy('thread.start_date')->get();
This will fetch all Post with Thread only if they have at least one Thread and then orderBy the start_date of the Thread.
You don't have to do the whereHas function because when you call ->with('thread') it'll use you this :
public function thread(): MorphOne
{
return $this->morphOne('App\Thread', 'postable')->orderBy('start_date');
}
whereHas doesnt retrieve the relationship.
If you need even more power, you may use the whereHas and orWhereHas methods to define additional query constraints on your has queries, such as inspecting the content of a comment: Laravel whereHas
Don't do :
$posts = Post::with('thread')->orderBy('thread.start_date');
If there is no thread on some post, post without thread will be fetch with value null for their key thread and you will have an unexpected result when you try to orderBy.
First of all I want to thank Elie Morin for his help but I found out that I definitely need to use joins for that task.
In my example, I wanted to order the main query (posts) by the relation's start_date
Doing what you suggested
$posts = Post::with('thread')->has('thread')->orderBy('thread.start_date')->get();
Would only order the thread by start_date and not the ENTIRE query.
Which is why I came up with something like this:
$posts = Post::has('thread')
->select('posts.id')
->leftJoin(
'thread',
'posts.id',
'=',
'thread.postable_id'
)
->where('thread.postable_type', '=', 'App\Post')
->where('thread.end_date', '>=', Carbon::now())
->orderBy('thread.start_date')
->with('thread');
return PostResource::collection($posts->paginate(2));

Eloquent, Retrieve results from nested relations query

Here is my query:
$profile = \App\ShippingProfile::findOrFail(2)
::with('costs')
->with( ['methods.zone' => function($query) {
$query->where('id', 2);
}])->get();
So I need shipping profile id 2, with related "costs" model and its related "method" with id 2, and the method's related "zone".
But I don't know how to get the result. If I try ->get() , I get all ShippingProfiles, and if try
->first() I get profile id 1.
So how would I retrieve the results? I have only seen "get", "first" and "find"...or is there something wrong with the query?
There are a few problems with your current code. First of all you have a syntax error:
$profile = \App\ShippingProfile::findOrFail(2)
::with('costs')
The second :: should be ->.
Secondly, when you do firstOrFail() you're actually executing the query and returning a Model as a result. So when you're then chaining the rest onto the Model instance you're likely ending up with an error.
There are a couple of ways you can achieve your goal however. First of all, try using whereKey which adds a where clause to your query against the primary key, (just like using findOrFail does - but it doesn't immediately execute the query and return the model) and use first() to grab the model instance with the relations eager loaded:
$profile = \App\ShippingProfile::whereKey(2)
->with(['costs', 'method.zone' => function ($query) {
$query->where('id', 2);
}])
->first();
Alternatively, if you already have an instance of your model, you can use load(...), in the same way as you would use with(...) to load your relations:
$profile = App\ShippingProfile::findOrFail(2);
$profile->load(['costs', 'method.zone' => function ($query) {
$query->where('id', 2);
}]);

How to get items from collection by created_at date with using only Y-m-d part?

I have a collection with records that include the created_at row. Now i want to get specific rows by date without time. I mean :
$users->whereLoose('created_at', '2016-11-23')
of course this returns empty but the format I need to use is "Y-m-d" without the "H:i:s" part. How can use this format to get records from the collection?
You could also use the filter method and the isSameDay() method.
$date = \Carbon\Carbon::parse('2016-11-23');
$usersForDate = $users->filter(function ($user) use ($date) {
return $user->created_at->isSameDay($date);
});
Hope this helps!
You can do this:
$date = Carbon::parse('2016-11-23');
$users->where('created_at', '>', $date->startOdDay())
->where('created_at', '<', $date->endOfDay());
Or you could try this:
$users->whereDate('created_at', '=', '2016-11-23');
You can try using the map() function on the collection per the docs https://laravel.com/docs/5.2/collections:
https://laravel.com/docs/5.2/collections#method-map
$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
return strtoupper($name);
})
->reject(function ($name) {
return empty($name);
});

Resources