laravel 中 queryScope 的复杂查询约束
Complex query constraint on queryScope in laravel
用户 table 有以下列:
- created_at(时间戳)
- last_order(时间戳)
创建新用户时,last_order 为空,created_at 为当前时间戳。
当用户下订单时,最后一个订单列将更新为下订单时间的时间戳。
现在我想检索过去 7 天未下任何订单的所有用户。我定义我的用户模型如下:
class User extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'users';
/**
* @var array Validation rules
*/
public $rules = [
];
public $hasMany = [
'voucher' => ['ItScholarBd\Api\Models\Voucher'],
'order' => ['ItScholarBd\Api\Models\OrderLog']
];
public function scopeCustomer($query)
{
return $query->where('role_id', '=', 5);
}
public function scopeNew($query,$days)
{
return $query->where('created_at', '>=', Carbon::now()->subDays($days));
}
public function scopeIdle($query,$days)
{
$dayOffset = Carbon::now()->subDays($days);
return $query->where(function($q,$dayOffset){
$q->whereNull('last_order')
->where('created_at','<',$dayOffset);
})->orWhere(function($q,$days){
$q->whereNotNull('last_order')
->whereRaw("DATEDIFF(created_at,last_order)>$days");
});
}
}
此处 scopeNew()
运行良好,但 scopeIdle()
抛出以下错误:
Type error: Too few arguments to function App\User::App\{closure}(),
1 passed in .\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php on line 222 and exactly 2 expected
尝试使用闭包:
return $query->where(function($q) use ($dayOffset){
您无法为您无法控制的功能编造参数。闭包将传递一个参数,您需要使用 use
:
导入任何其他变量
public function scopeIdle($query, $days)
{
$dayOffset = Carbon::now()->subDays($days);
return $query
->where(function ($q) use ($dayOffset) {
$q->whereNull('last_order')
->where('created_at', '<', $dayOffset);
})
->orWhere(function ($q) use ($days) {
$q->whereNotNull('last_order')
->whereRaw("DATEDIFF(created_at, last_order) > ?", [$days]);
});
}
注意whereRaw
语句中参数的使用,可以避免SQL注入。如果您始终如一地缩进 space,您还会发现您的代码更易于处理。
用户 table 有以下列:
- created_at(时间戳)
- last_order(时间戳)
创建新用户时,last_order 为空,created_at 为当前时间戳。 当用户下订单时,最后一个订单列将更新为下订单时间的时间戳。 现在我想检索过去 7 天未下任何订单的所有用户。我定义我的用户模型如下:
class User extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'users';
/**
* @var array Validation rules
*/
public $rules = [
];
public $hasMany = [
'voucher' => ['ItScholarBd\Api\Models\Voucher'],
'order' => ['ItScholarBd\Api\Models\OrderLog']
];
public function scopeCustomer($query)
{
return $query->where('role_id', '=', 5);
}
public function scopeNew($query,$days)
{
return $query->where('created_at', '>=', Carbon::now()->subDays($days));
}
public function scopeIdle($query,$days)
{
$dayOffset = Carbon::now()->subDays($days);
return $query->where(function($q,$dayOffset){
$q->whereNull('last_order')
->where('created_at','<',$dayOffset);
})->orWhere(function($q,$days){
$q->whereNotNull('last_order')
->whereRaw("DATEDIFF(created_at,last_order)>$days");
});
}
}
此处 scopeNew()
运行良好,但 scopeIdle()
抛出以下错误:
Type error: Too few arguments to function App\User::App\{closure}(),
1 passed in .\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php on line 222 and exactly 2 expected
尝试使用闭包:
return $query->where(function($q) use ($dayOffset){
您无法为您无法控制的功能编造参数。闭包将传递一个参数,您需要使用 use
:
public function scopeIdle($query, $days)
{
$dayOffset = Carbon::now()->subDays($days);
return $query
->where(function ($q) use ($dayOffset) {
$q->whereNull('last_order')
->where('created_at', '<', $dayOffset);
})
->orWhere(function ($q) use ($days) {
$q->whereNotNull('last_order')
->whereRaw("DATEDIFF(created_at, last_order) > ?", [$days]);
});
}
注意whereRaw
语句中参数的使用,可以避免SQL注入。如果您始终如一地缩进 space,您还会发现您的代码更易于处理。