Reputation: 797
I'm refactoring my application towards proper MVC and moving all my business logic to my models. However, in a certain situation this causes a noticeable performance drop.
My model 'User' has a hasmany relationship with the model 'Log'. There's a certain function in my User model that return its logs between a certain date. I filter the collection like this:
public function getLogsBetweenDates($start, $end) {
$logs = $this->logs
->filter(function($value, $key) use ($start, $end) {
return $value->log_date >= $start && $value->log_date <= $end;
});
return $logs
}
This works but its a lot slower than my previous implementation which was accessing my LogRepository in my controller.
public function getLogsBetweenDateFromUser($start_date, $end_date, $user_id)
{
$start = Carbon::parse($start_date);
$end = Carbon::parse($end_date);
return Log::where('user_id', $user_id)
->where('log_date', '>=' , $start)
->where('log_date', '<=' , $end)
->get();
}
It probably has to do with how Eloquent manages retrieving relationships. I would like to keep the code in my User model but not with the performance drop. Does someone know where this performance drop exactly comes from and how I could solve this?
Upvotes: 1
Views: 2759
Reputation: 817
Filtering collections means that you read everything from the database, create objects for each record and then filter. It is normal that it takes much more time. The solution, no matter the architecture, is to do it the second way, using Eloquent filtering.
Upvotes: 2