I have a simple script in post.blade.php
{{ Auth::user() ? ($post->ratings()->where('user_id', Auth::user()->id)->exists() ? 'You rated ' . $post->userRating($post) : '') : '' }}
The 2 functions that get access in my post model are:
public function ratings() {
return $this->hasMany(Rating::class);
}
public function userRating(Post $post) {
return $this->ratings()->where([
['post_id', '=', $post->id],
['user_id', '=', Auth::user()->id]
])->first('stars')->stars / 2;
}
This is the index in my postcontroller:
public function index() {
$posts = Post::with('user')->withAvg('ratings', 'stars')->paginate(100);
return view('posts.index', [
'posts' => $posts,
]);
}
This however takes about 1 second to load each page because it has to execute that code 100 times.
If I remove the script mentioned at the top from the blade file the page loads way faster.
I made this query in raw MySQL and it loads the results significantly faster:
select `posts`.*, (select avg(`ratings`.`stars`) from `ratings` where `posts`.`id` = `ratings`.`post_id`) as `ratings_avg_stars`, (SELECT count(*) FROM ratings WHERE post_id = posts.id and user_id = 1) as rated from `posts` where `posts`.`deleted_at` is null
If I were to put that in my postcontroller I think the page would load faster, I don't know how to convert the MySQL to Eloquent, I have tried a query converter but those get stuck on the subqueries.
How can I convert the MySQL query to an Eloquent query?