How to automatically filter foreign table's deleted_at = null while using join in laravel eloquent?

huangapple go评论59阅读模式
英文:

How to automatically filter foreign table's deleted_at = null while using join in laravel eloquent?

问题

现在 ->join() 是一个查询构建器,因此它不会使用具有 SoftDelete 的模型,我的项目中有太多使用 join 的代码,所以我不想手动用 eager loading ->with() 替换它,有人知道如何在保持 join 的情况下做到这一点吗?

例如,我想获取这样的数据,而不必在所有代码中添加 ->where('tb_b.deleted_at', null):

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

英文:

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()

答案1

得分: 1

Sure, here are the translated parts:

  1. 通过使用 whereNull 约束来解决此问题
$data = TabelA::join('tb_b', 'tb_a.id_b', '=', 'tb_b.id_b')
    ->whereNull('tb_b.deleted_at')
    ->get();
  1. 在您的模型中创建一个全局范围(这里,我将假设 TbB 模型)。将以下函数添加到您的模型类中,以创建一个全局范围,自动过滤您的模型获取方法。
public static function boot()
{
    parent::boot();

    static::addGlobalScope('notDeleted', function (Builder $builder) {
        $builder->where('deleted_at', null);
    });
}

然后,在您需要获取没有被删除的数据时,您将执行以下操作:

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

在此处阅读更多关于 Laravel 范围的信息:https://learn2torials.com/a/laravel8-global-model-scope

英文:

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

答案2

得分: 0

  1. 在连接后添加一个WHERE子句
TabelA::query()
    ->join('tb_b', 'tb_a.id_b', '=', 'tb_b.id_b')
    ->whereNull('tb_b.deleted_at')
    ->get()
  1. 在连接中添加一个AND子句
TabelA::query()
    ->join(function ($join) {
        $join->on('tb_b', 'tb_a.id_b', '=', 'tb_b.id_b')
            ->whereNull('tb_b.deleted_at');
    })
    ->get()
  1. 在子查询上进行连接
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()
英文:

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()

huangapple
  • 本文由 发表于 2023年5月17日 09:12:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76267976.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定