Laravel最佳实践--根据搜索参数为Model查询应用不同的Where条件

0

我们平时使用Laravel的Model查询当查询应用了多个条件的时候一般都是链式调用,像下面这样:

User::where('age', '=', 18)
    ->where('sex', '=', 'male')
    ->where('nation' '=', 'US')
    ->get();

不过在做数据搜索的时候往往会遇到根据搜索参数应用不同的查询条件,比如说参数里有age值时才会给查询应用上age = value的条件搜索参数里没有age的话不对搜索的年龄进行限制。那么在Laravel里如何优雅地让查询根据参数条件应用上不同的where条件呢?我们来看一下

$query = User::newQuery();
$params['age'] && $query->where('age', '=', $param['age']);
$params['sex'] && $query->where('sex', '=', $params['sex']);
$params['nation'] && $query->where('nation', '=', $params['nation']);
$query->get();

这样就能根据参数来为查询应用不同的条件来,不过还不够优雅,我们把这几个where条件封装到Model的查询作用域中,这样在其它地方应用到这些查询的时候就不用再重复地写一堆where条件了

//User Model
public function scopeWhereAge($query, $age)
{
    return $query->where('age', '=', $age);
}

public function scopeWhereSex($query, $sex)
{
    return $query->where('sex', '=', $sex);
}

public function scopeWhereNation($query, $nation)
{
    return $query->where('nation', '=', $nation)
}

接下来我们把之前代码块里的where条件都换成调用查询作用域的形式:

$query = User::query();
$params['age'] && $query->whereAge($param['age']);
$params['sex'] && $query->whereSex($params['sex']);
$params['nation'] && $query->whereNation($params['nation']);
$query->get();

为了方便调用我们把上面这个代码块封装到UserSerivce

namespace App\Services;
use App\Models\User;
class UserService
{
    public function userList($params)
    {
        $query = User::query();
        $params['age'] && $query->whereAge($param['age']);
        $params['sex'] && $query->whereSex($params['sex']);
        $params['nation'] && $query->whereNation($params['nation']);
        //$query->toSql();查看生成的SQL
        return $query->get();
    }
}

之后在用到搜索获取用户列表的地方注入UserService就能调用UserServiceuserList方法获取用户列表了。


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

almas1992 · 3月10日

where后面本来就可以直接加字段名,不用定义scope,Laravel已经用魔术方法处理了

回复

Birjemin · 7月22日

楼上说的对,whereAge是自带的,没必要再scope一遍,scope可用于逻辑上的,比如scopeIsChild($query) {return $this->age > 18 ? true : false;}

回复

载入中...