Querying a database relationship with carbon in laravel - laravel

I'm trying to select the picture with the most likes from a category the previous day. However, my query returns a null result. My pictures are related to the likes through a has many polymorphic relationship.
Here is my query:
$foodOfTheDay = Picture::withCount('likes')
->where('picture_type', 'food')
->whereHas('likes', function($query) {
$query->whereDate('created_at', Carbon::yesterday());
})
->orderBy('likes_count', 'desc')
->with('user')
->first();
Here is my likeable relationship:
public function likes()
{
return $this->morphMany('App\Like', 'likeable');
}
Thank you for your help.

Try this:
$foodOfTheDay = Picture::withCount('likes')
->where('picture_type', 'food')
->whereHas('likes', function($query) {
$query->whereBetween('created_at', [Carbon\Carbon::yesterday()->startOfDay(), Carbon\Carbon::yesterday()->endOfDay()]);
})
->withCount('likes') // count yesterday's likes
->orderBy('likes_count', 'desc')
->with('user')
->first();
or this:
$foodOfTheDay = Picture::withCount('likes')
->where('picture_type', 'food')
->whereHas('likes', function($query) {
$query->where('created_at', '>=', Carbon::yeserday()->startOfDay())
->where('created_at', '<=', Carbon::yesterday()->endOfDay());
})
->withCount('likes') // count yesterday's likes
->orderBy('likes_count', 'desc')
->with('user')
->first();
Both of them should return picture with the highest likes the previous day (yesterday)
This query selects the picture with most likes without taking into consideration the other days' likes:
$foodOfTheDay = Picture::where('picture_type', 'food')->withCount(['likes' => function($query) {
$query->whereBetween('created_at', [Carbon::yesterday()-
>startOfDay(), Carbon::yesterday()->endOfDay()]);
}])
->orderBy('likes_count', 'asc')
->with('user')
->first();

Related

Laravel model get all results, but if model has relation then check for certain condition

Assume I have book models and borrow models. They are one-to-many relationships. I want to get a collection of all the books but return the result if the book is borrowed within the current week. But if it's not, then don't display. I've been trying whereHas(), but I think it didn't suit what I'm looking for.
$displayed_books = Books::orderBy('updated_at', 'DESC')
->ifHasborrow('borrow', function ($query) {
$query->where('start_date', '>=', currentweek())
->where('end_date', "<=", currentweek());
})
$displayedBooks = Books::orderBy('updated_at', 'DESC')
->where(function ($query) {
$query->whereHas('borrow', function($query) {
$now = Carbon::now();
$query->where([
['start_date', '>=', $now->startOfWeek()],
['end_date', '<=', $now->endOfWeek()]
]);
$query->orWhereDoesntHave('borrow');
})
})->get();

Laravel Eloquent making select on whereHas()

How can I select on whereHas() some columns in relation.
My current query looks like as it follows
Location::select(['title'])
->withCount(['job' => function($q) {
return $q->where('language_id', 1)->whereNull('deleted_at');
}])->whereHas('country', function ($q) {
return $q->where('id', '=', 80);
})->get();
and I tried
Location::select(['title', 'id as value'])->withCount(['job' => function($q) {
return $q->where('language_id', 1)->whereNull('deleted_at');
}])->whereHas('country', function ($q) {
return $q->select('title', 'iso3')->where('id', '=', 80);
})->get();
but nothing is getting returned on country relation. How do I refactor this query to get it work?
whereHas() doesn't eager load the relation, only filters results based on it. To eager load, use with().
Location::with('country:id,title,iso3')
->select(['title', 'id as value', 'country_id'])
->withCount(['job' => function($q) {
$q->where('language_id', 1)->whereNull('deleted_at');
}])
->whereHas('country', function ($q) {
$q->where('id', '=', 80);
})->get();

Laravel eloquent model where datetime less than or equal

I am having an expire_datetime field in Test model and it has many relationship with Candidate model. I want to get all the tests which exipre_datetime is less than or equeal to now datetime. I am doing like this but I am getting all the records, date comparirion is not functioning.
Test Model:
public function testcandidates()
{
return $this->hasMany(Candidate::class,'test_id','id');
}
TestController:
$tests = Test::with([
'testcandidates' => function ($query) {
$query->where('result', '=', 'assigned');
}
])
->where('expire_datetime', '<=', Carbon::now('UTC'))
->get();
Try to get string from carbon: Carbon::now('UTC')->toDateTimeString()
$tests = Test::with(
['testcandidates' => function ($query) {
$query->where('result', '=', 'assigned');
}])
->where('expire_datetime', '<=', Carbon::now('UTC')->toDateTimeString())
->get();

Pull data based on related table

I have a tables:
events[id, 'name', 'date'],
tickets ['id', event_id', 'isAvailable'],
order_tickets ['order_id', 'ticket_id'],
orders['id', 'buyer_id', 'status'].
I need to receive all orders with tickets on the events, where date >= today (do not include tickets to past events.).
My query is next:
$userId = 1;
$orders = Order::with([
'tickets',
'tickets.event',
])->where('buyer_id', $userId)
->where('status', 'sold')
->get();
You can use the whereHas() method and the today() helper function to achieve this:
$orders = Order::with('tickets.event')
->whereHas('tickets.event', function ($query) {
$query->whereDate('date', '>=', today());
})
->where('buyer_id', $userId)
->where('status', 'sold')
->get();

Laravel 4 Eager Loading constraints

I want to get all Items (topics) WITH their comments, if comments user_id = $id. I try something like this, but it isn't working. So if Item hasn't got any comment with user_id = $id, then I don't need this Item.
In DiscussionsItem model I have methode:
public function discussionsComments() {
return $this->hasMany('DiscussionsComment', 'discussionsitem_id');
}
My query in controller is like this:
$items = DiscussionsItem::whereBrandId($brand_id)
->whereBrandCountryId($country_id)
->with(['discussionsComments' => function($query) use ($id) {
$query->where('user_id', '=', $id);
}])
->whereHas('discussionsComments', function($query) use ($id) {
$query->where('user_id', '=', $id);
})
->with(['views' => function($query) use ($id) {
$query->where('user_id', $id)->count();
}])
->orderBy('created_at', 'DESC')->get();
My problem is that I get items with comments, where comments user_id != $id.
P.S. I need to take 5 comments, but I cant imagine how to do that, because ->take(5) in my eager load is not working.
You can do a custom scope, or just limit the amount returned by your relation:
public function discussionsComments() {
return $this->hasMany('DiscussionsComment', 'discussionsitem_id')
->latest()
->take(5);
}

Resources