代码之家  ›  专栏  ›  技术社区  ›  fico7489

Laravel-如何用构建器上的where子句包围前面的所有子句?

  •  0
  • fico7489  · 技术社区  · 6 年前

    在数据库表中,我有一行:

    users
    id|email|is_deleted
    1|test@test.com|1
    

    我有这个密码:

    User::where('email', 'test@test.com')
        ->orWhere('email', 'test2@test2.com')
        ->get();
    

    select * from users where email = 'admin@myzone.com' or email = 'asdasdas'
    

    只有一个结果。现在我想申请

    如果我这样做:

    User::where('email', 'test@test.com')
        ->orWhere('email', 'test2@test2.com')
        ->where('is_deleted', 0)
        ->get();
    

    生成的查询是:

    select * from "users" where "email" = ? or "email" = ? and "users"."deleted_at" is null
    

    到目前为止,一切正常,这个查询返回一个结果,但我只想不删除用户,我可以做以下工作:

    User::where(function($query){
        $query->where('email', 'test@test.com')
            ->orWhere('email', 'test2@test2.com')
    })->where('is_deleted', 0)
    ->get();
    

    function applyNotDeleted(Builder $builder){
        //here I want to filter only not deleted users, 
        //but this is already triggered on builder $query->where('email', 'test@test.com')->orWhere('email', 'test2@test2.com')
    
        //currently generated query on builder is select * from users where email = 'admin@myzone.com' or email = 'asdasdas'
        //but at this stage I want to create query which will look like select * from "users" where "email" = ? or "email" = ? and "users"."deleted_at" is null
    
        //something like this 
        $builderNew = $builderNew->where(function($query){
            $query->applyAllLogicFromCurrentBuilder($builder)
        })
        ->where('is_deleted', 0)
        ->get();
    }
    

    知道吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Sebastian Sulinski    6 年前

    我个人会使用查询范围来获取未删除的记录

    public function scopeNotDeleted(Builder $query): Builder
    {
        return $query->where('is_deleted', 0);
    }
    

    然后在获取记录时使用它

    User::notDeleted()->where(function(Builder $query) {
        $query->where('email', 'test@test.com')->orWhere('email', 'test2@test2.com');
    })->get();
    

    如果你正在使用 applyAllLogicFromCurrentBuilder 方法,您还可以将其提取到查询范围,并将其与调用链接起来,如下所示:

    User::allLogicFromCurrentBuilder()->notDeleted()->where(function(Builder $query) {
        $query->where('email', 'test@test.com')->orWhere('email', 'test2@test2.com');
    })->get();
    

    你也可以 applyNotDeleted get() 方法-这样,如果需要,您可以向它附加任何进一步的语句。我可能会把它转换成 public static

    User::applyNotDeleted(User::where(function(Builder $query) use ($email) {
        $query->where('email', 'test@test.com')->orWhere('email', 'test2@test2.com');
    }))->get();
    

    就我个人而言,我更喜欢范围方法,因为它看起来有点干净。