Laravel 查询:获取 child 的日期范围不在日期范围数组中的模型
Laravel Query: get models where child's date ranges is not in array of date ranges
我有 Event
个模型,hasMany
个孩子有 Time
个模型。
Time
是具有 start_time
和 end_time
字段的日期时间范围。
如何获得所有 Events
其中 none 的孩子 Times
与 array
的日期范围相交?
示例:
$events = Event::notInDateRange([
[ 'start_date' => '2000.01.01 00:00:00', 'end_date' => '2000.01.01 12:00:00' ],
[ 'start_date' => '2000.01.02 12:00:00', 'end_date' => '2000.01.02 16:00:00' ],
[ 'start_date' => '2000.01.03 10:00:00', 'end_date' => '2000.01.03 12:30:00' ],
])->get();
// In this case I don't want to get Event where one of Time is
// [ 'start_date' => '2000.01.03 12:00:00' => 'end_date' => '2000.01.03 14:00:00' ]
您可以在新范围内创建一个新的 query scope to create a notInDateRange
scope in your Event
model and use the whereNotBetween
where clause。
在您的 Event
模型 class 中,定义一个名为 scopeNotInDateRange
的新函数,它接受开始和结束日期并将其定义如下:
public function scopeNotInDateRange($query, $start_date, $end_date)
$start = new Carbon($start_date);
$end = new Carbon($end_date);
return $query->whereNotBetween('start_date', [$start, $end])
->whereNotBetween('end_date', [$start, $end]);
另外记得将 use Carbon\Carbon;
添加到 Event
class 的顶部。我们将使用 Carbon 将字符串转换为日期。
然后您可以使用新的查询范围,例如 App\Event::notInDateRange($start, $end)
。您还可以链接范围,因此在您的示例中您可以使用:
$events = Event::notInDateRange('2000-01-01 00:00:00', '2000-01-01 12:00:00')
->notInDateRange('2000-01-02 12:00:00', '2000-01-02 16:00:00')
->notInDateRange('2000-01-03 10:00:00', '2000-01-03 12:30:00')
->get();
请注意,我还将您在日期中使用的 .
更改为 -
,以便 Carbon 能够将字符串转换为日期。
如果您还没有,还请确保您的 start_date
和 end_date
列已使用 Date Mutators 转换为碳日期,当您使用 Laravel.为此,请将以下代码段添加到您的 Event
模型 class:
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = [
'start_date', 'end_date'
];
我有 Event
个模型,hasMany
个孩子有 Time
个模型。
Time
是具有 start_time
和 end_time
字段的日期时间范围。
如何获得所有 Events
其中 none 的孩子 Times
与 array
的日期范围相交?
示例:
$events = Event::notInDateRange([
[ 'start_date' => '2000.01.01 00:00:00', 'end_date' => '2000.01.01 12:00:00' ],
[ 'start_date' => '2000.01.02 12:00:00', 'end_date' => '2000.01.02 16:00:00' ],
[ 'start_date' => '2000.01.03 10:00:00', 'end_date' => '2000.01.03 12:30:00' ],
])->get();
// In this case I don't want to get Event where one of Time is
// [ 'start_date' => '2000.01.03 12:00:00' => 'end_date' => '2000.01.03 14:00:00' ]
您可以在新范围内创建一个新的 query scope to create a notInDateRange
scope in your Event
model and use the whereNotBetween
where clause。
在您的 Event
模型 class 中,定义一个名为 scopeNotInDateRange
的新函数,它接受开始和结束日期并将其定义如下:
public function scopeNotInDateRange($query, $start_date, $end_date)
$start = new Carbon($start_date);
$end = new Carbon($end_date);
return $query->whereNotBetween('start_date', [$start, $end])
->whereNotBetween('end_date', [$start, $end]);
另外记得将 use Carbon\Carbon;
添加到 Event
class 的顶部。我们将使用 Carbon 将字符串转换为日期。
然后您可以使用新的查询范围,例如 App\Event::notInDateRange($start, $end)
。您还可以链接范围,因此在您的示例中您可以使用:
$events = Event::notInDateRange('2000-01-01 00:00:00', '2000-01-01 12:00:00')
->notInDateRange('2000-01-02 12:00:00', '2000-01-02 16:00:00')
->notInDateRange('2000-01-03 10:00:00', '2000-01-03 12:30:00')
->get();
请注意,我还将您在日期中使用的 .
更改为 -
,以便 Carbon 能够将字符串转换为日期。
如果您还没有,还请确保您的 start_date
和 end_date
列已使用 Date Mutators 转换为碳日期,当您使用 Laravel.为此,请将以下代码段添加到您的 Event
模型 class:
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = [
'start_date', 'end_date'
];