skip to Main Content

As it is right now ->join() is a query builder so it wouldn’t using Model that has SoftDelete, there is too many codes that used join in my project so I don’t want to manually replace it all with eager loading ->with(), anyone know how to do it while keeping the join?

For example I want to get a data like this without adding ->where(‘tb_b.deleted_at’, null) to all my codes:

$data = TabelA::join('tb_b', 'tb_a.id_b', '=', 'tb_b.id_b')->get()

2

Answers


  1. Three alternatives

    1. Adding a WHERE clause after the join
    TabelA::query()
        ->join('tb_b', 'tb_a.id_b', '=', 'tb_b.id_b')
        ->whereNull('tb_b.deleted_at')
        ->get()
    
    1. Adding an AND clause to the join
    TabelA::query()
        ->join(function ($join) {
            $join->on('tb_b', 'tb_a.id_b', '=', 'tb_b.id_b')
                ->whereNull('tb_b.deleted_at');
        })
        ->get()
    
    1. Joining on a subquery.
    TabelA::query()
        ->joinSub(
            function ($sub) {
                $sub->from('tb_b')
                    ->whereNull('tb_b.deleted_at');
            }),
            'tb_b_alias',
            'tb_b_alias.id_b',
            '=',
            'tb_a.id_b'
        )
        ->get()
    
    Login or Signup to reply.
  2. There are basically two ways to solve this

    1. By using a whereNull constraint
    $data = TabelA::join('tb_b', 'tb_a.id_b', '=', 'tb_b.id_b')
        ->whereNull('tb_b.deleted_at')
        ->get();
    
    1. Creating a global scope in your model (here, I will assume TbB Model). Add the following function in your model class to create a global scope to automatically filter your model get method.
    public static function boot()
    {
        parent::boot();
    
        static::addGlobalScope('notDeleted', function (Builder $builder) {
            $builder->where('deleted_at', null);
        });
    }
    

    Then, you will do this when you need your data without the deleted data

    $data = TabelA::withoutGlobalScope('notDeleted')
        ->join('tb_b', 'tb_a.id_b', '=', 'tb_b.id_b')
        ->get();
    

    Read more on Laravel scope here: https://learn2torials.com/a/laravel8-global-model-scope

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search