justinkekeocha / udemy

Udemy clone using VITL stack: Vue, Inertia.JS, TailwindCSS and Laravel
https://udemy.jaycode.dev
2 stars 0 forks source link

Load relations instead of fetching them separately #1

Open newtonjob opened 1 year ago

newtonjob commented 1 year ago

https://github.com/justinkekeocha/udemy/blob/fdc6555aeeb4da81cfde8a64064899905aeb411f/app/Http/Controllers/CategoryController.php#L54

It's usually a good idea to load a model's relations and pass just the model resource to Inertia, instead of fetching the relations separately and using different variables/props.

For example, instead of;

        $model = $category;
        $model = new CategoryResource($model);
        $topics = TopicResource::collection($model->topics->take(20));
        $courses = CourseResource::collection($model->courses);
        //https://laravel.com/docs/10.x/eloquent-relationships#deferred-count-loading
        //https://laravel.com/docs/10.x/eloquent-relationships#lazy-eager-loading
        $instructors =  UserResource::collection($model->instructors->loadCount('instructedCourses'));

        // dd($courses->take(20));
        return Inertia::render("Courses/Show", compact('model', 'courses', 'topics', 'instructors'));

You might do something like;

        $category->load(['topics', 'courses', 'instructors' => fn ($query) => $query->withCount('instructedCourses')]);

        return Inertia::render("Courses/Show", compact('category'));
justinkekeocha commented 1 year ago

I usually load direct parent relationships by default on the model using the $with property.

For example I load the topic a course belongs to in the course model and category a topic belongs to in the topic model.

So course->topic->category.

This is to reduce the number of places I eager load. Using those defined relationships and trying to do:

$category->load(['topics', 'courses', 'instructors' => fn ($query) => $query->withCount('instructedCourses')]); Will lead to a recursive loop and HTTP 500.

This was what inspired this article: https://carlesto.com/blog/posts/460/laravel-eloquent-relationships-with-property-http-500-error

What do you think? Is there a better way you would do this?

I didn't know I could do this: 'instructors' => fn ($query) => $query->withCount('instructedCourses').

Thanks for the tip.