Devpat's avatar

So im making an API using lumen.

i made a list courses that can sort ascending and descending by typing 'sort = a' and 'sort = b' as well as list the courses. now im having trouble building a filter. i really cant get it. hoping you could help me understand my problem and do you think my sorting is correct? here's my code

<?php

CONTROLLER:

public function listCourses(Request $r)
    {
        $sort               = $r->get('sort');
        $category_id        = $r->get('category_id');

        $courses = $this->course_discovery->listCourses();

        $sortOrder = $sort == 'a' ? 'asc' : 'desc';

        if ($sort == 'a' OR $sort == 'd') { //input sort a and sort d to sort
            $courses = $this->course_discovery
                ->select('course.course_id', 'course.course_title', 'course.course_overview', 'category.category_name', 'course_level.course_difficulty')
                ->join('category', 'course.category_id', '=', 'category.category_id')
                ->join('course_level', 'course.course_level_id', '=', 'course_level.course_level_id')
                ->orderBy('category.category_name', $sortOrder)
                ->orderBy('course.course_title', $sortOrder)
                ->paginate(5);

        }  
        
        return response()->json([
            'Result' => $courses
        ]);
    }



MODEL

public function listCourses()
    {
        $courses = $this->select('course.course_id', 'course.course_title', 'course.course_overview', 'category.category_name', 'course_level.course_difficulty')
                ->join('category', 'course.category_id', '=', 'category.category_id')
                ->join('course_level', 'course.course_level_id', '=', 'course_level.course_level_id')
                ->paginate(10);

        // $courses = $this->get();

        return $courses;
    }
0 likes
1 reply
tykus's avatar
tykus
Best Answer
Level 104

I believe it might be more appropriate to return a Builder instance from the model:

// Model

public function listCourses()
{
    return static::select('course.course_id', 'course.course_title', 'course.course_overview', 'category.category_name', 'course_level.course_difficulty')
            ->join('category', 'course.category_id', '=', 'category.category_id')
            ->join('course_level', 'course.course_level_id', '=', 'course_level.course_level_id')
}

and use it in the controller as a Builder instance to modify the query as required:

public function listCourses(Request $r)
{
    $sortOrder = $r->get('sort') == 'a' ? 'asc' : 'desc';
    $category_id = $r->get('category_id');

    /** @var Illuminate\Database\Eloquent\Builder $builder */
    $builder = $this->course_discovery->listCourses();
    $builder->orderBy('category.category_name', $sortOrder)
        ->orderBy('course.course_title', $sortOrder);
    }

    // Now chain your filters *if* there is a value, for example:
    $builder->when($category_id, function ($query) use ($category_id) {
        $query->where('category_id', $category_id);
    });
    
    return response()->json([
        'Result' => $builder->paginate(10) // finish your query
    ]);
}

This could be optimised further using local query scopes on the model, but you get the idea

1 like

Please or to participate in this conversation.