demonz's avatar

how to search using scope but with db raw

Hi guys , I am having hard time here, i have 4 batches with same code, and what i do is to take first batch then edit start_date to min start_date and end_date to max end_date and then change the value of status based on certain cases.

now the issue is every time i search it doesn't search for start_date based on the value retrieved from DB::raw but it go check the original row, how to solve this ? any suggestion ? thanks.

public function index()
{
    return Inertia::render('Batch/Program/Index', [
        'filters' => Request::all('search'),
        'batches' => new BatchCollection(
            Batch::select(
                'id',
                'batch_code',
                'program_id',
                DB::raw('(SELECT MIN(start_date) FROM batches b WHERE b.batch_code = batches.batch_code) as start_date'),
                DB::raw('(SELECT MAX(end_date) FROM batches b WHERE b.batch_code = batches.batch_code) as end_date'),
                DB::raw('(SELECT SUM(total_sessions) FROM batches b WHERE b.batch_code = batches.batch_code) as total_sessions'),
                DB::raw('CASE
                WHEN
                    (SELECT status FROM batches b WHERE b.batch_code = batches.batch_code AND b.start_date = (SELECT MIN(start_date) FROM batches b2 WHERE b2.batch_code = batches.batch_code)) = "completed"
                THEN
                    (SELECT
                        CASE
                            WHEN COUNT(*) > 0 THEN "running"
                            ELSE "upcoming"
                        END
                    FROM batches b3
                    WHERE b3.batch_code = batches.batch_code AND b3.start_date > (SELECT MIN(start_date) FROM batches b2 WHERE b2.batch_code = batches.batch_code))
                ELSE
                    (SELECT status FROM batches b WHERE b.batch_code = batches.batch_code AND b.start_date = (SELECT MIN(start_date) FROM batches b2 WHERE b2.batch_code = batches.batch_code))
                END AS status'),
                DB::raw('(SELECT location_id FROM batches b WHERE b.batch_code = batches.batch_code AND b.start_date = (SELECT MIN(start_date) FROM batches b2 WHERE b2.batch_code = batches.batch_code)) as location_id')
            )
            ->whereHas('program')
            ->where('start_date', function ($query) {
                $query->selectRaw('MIN(start_date)')
                    ->from('batches as b2')
                    ->whereRaw('b2.batch_code = batches.batch_code');
            })
            ->with(['program:id,name', 'location'])
            ->withCount('learners')
            ->orderBy('start_date')
            ->filterProgram(Request::only('search'))
            ->paginate(5)
            ->appends(Request::all())
            )
    ]);
}

and this is the scope

    public function scopeFilterProgram($query, array $filters)
    {
        $query->when($filters['search'] ?? null, function ($query, $search) {
            $query->where(function ($query) use ($search) {
                $query->where('batch_code', 'like', '%'.$search.'%')
                      ->orWhereHas('program', function ($query) use ($search) {
                          $query->where('name', 'like', '%'.$search.'%');
                      })
                      ->orWhere('start_date', 'like', '%'.$search.'%')
                      ->orWhere('end_date', 'like', '%'.$search.'%')
                      ->orWhere('status', 'like', '%'.$search.'%');
            });
        })->when($filters['trashed'] ?? null, function ($query, $trashed) {
            if ($trashed === 'with') {
                $query->withTrashed();
            } elseif ($trashed === 'only') {
                $query->onlyTrashed();
            }
        });
    }
0 likes
1 reply
demonz's avatar

it seems working using this


  public function scopeFilterProgram($query, array $filters)
    {
        $query->when($filters['search'] ?? null, function ($query, $search) {
            $query->where(function ($query) use ($search) {
                $query->where('batch_code', 'like', '%'.$search.'%')
                      ->orWhereHas('program', function ($query) use ($search) {
                          $query->where('name', 'like', '%'.$search.'%');
                      })
                      ->orWhere(function ($query) use ($search) {
                          $query->whereRaw('(SELECT MIN(start_date) FROM batches b WHERE b.batch_code = batches.batch_code) LIKE ?', ['%'.$search.'%'])
                                ->orWhereRaw('(SELECT MAX(end_date) FROM batches b WHERE b.batch_code = batches.batch_code) LIKE ?', ['%'.$search.'%'])
                                ->orWhereRaw('(SELECT
                                                  CASE
                                                      WHEN (SELECT status FROM batches b WHERE b.batch_code = batches.batch_code AND b.start_date = (SELECT MIN(start_date) FROM batches b2 WHERE b2.batch_code = batches.batch_code)) = "completed"
                                                      THEN
                                                          CASE
                                                              WHEN COUNT(*) > 0 THEN "running"
                                                              ELSE "upcoming"
                                                          END
                                                      ELSE
                                                          (SELECT status FROM batches b WHERE b.batch_code = batches.batch_code AND b.start_date = (SELECT MIN(start_date) FROM batches b2 WHERE b2.batch_code = batches.batch_code))
                                                  END) LIKE ?', ['%'.$search.'%']);
                      });
            });
        })->when($filters['trashed'] ?? null, function ($query, $trashed) {
            if ($trashed === 'with') {
                $query->withTrashed();
            } elseif ($trashed === 'only') {
                $query->onlyTrashed();
            }
        });
    }

Please or to participate in this conversation.