简体   繁体   中英

How to join results as an array of objects and filter, sort and paginate them in Laravel?

I have been working a project where activities can be graded in different ways using competences. Among many, I have two tables schemas that I am working on.

Table: Activities

  1. id
  2. name
  3. isNewest //currently always 1

Table: activity_competences //link table between activities, framework_competences and sub_competences

  1. id
  2. activity_id (foreign_key)
  3. framework_competence_id (foreign_key)
  4. master_competence_id (foreign_key)

Table: framework_competences

  1. id
  2. name

Table: master_competences

  1. id
  2. name

I want to fetch all the activities and its corresponding competences using SQL join. I also want the user to be able to filter and sort these results so they can only see the activities with the competence they need.

This is what I currently have.


        $paginateOffset = isset($request->paginateOffset) ? $request->paginateOffset : 0;
        $currentSort = isset($request->currentSort) ? $request->currentSort : 'id';
        $currentSortDir = isset($request->currentSortDir) ? $request->currentSortDir : 'desc';


        $activities = Activity::where('isNewest', 1)
        ->leftJoin('activity_competences', 'activities.id', '=', 'activity_competences.activity_id')
        ->leftJoin('framework_competences', 'activity_competences.framework_competence_id', '=', 'framework_competences.id')
        ->leftJoin('master_competences', 'activity_competences.master_competence_id', '=', 'master_competences.id')
        ->where(function($query) use ($request){//filter using keyword that user enters.
            $query->where('activities.name', 'LIKE','%'.$request->keyword.'%')
            ->orwhere('framework_competences.name', 'LIKE','%'.$request->keyword.'%')
            ->orwhere('master_competences.name', 'LIKE','%'.$request->keyword.'%');
        })->orderBy($currentSort, $currentSortDir)->offset($paginateOffset)->limit($paginateAmmount)
        ->get(array('activities.*', 'framework_competences.name as framework_competences', 'master_competences.name as master_competences'));


The response I get is:

[
    {
        "id": 1,
        "name": "activity1",
        "framework_competences": 'name1',
        "master_competences": 'name3',
        "isNewest": 1
    },
    {
        "id": 2,
        "name": "activity2",
        "framework_competences": 'name2',
        "master_competences": 'name4',
        "isNewest": 1
    }
]

but what I would like is:

[
    {
        "id": 1,
        "name": "manjil",
        "framework_competences": [name1, name2],
        "master_competences": [name3, name4]

    }
]

You can achieve this by creating relationships functions in your model, Activities.

For example:


public function framework() {
return $this->hasMany(FrameworkCompetences::class);
}

Then you would use the with() function to get this data in your collection when fetching, like $activities = Activity::with('framework','master')->get();

Read more about it on: https://laravel.com/docs/9.x/eloquent-relationships

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM