我有Event
个孩子hasMany
个模型的Time
个模型。
Time
是具有start_time
和end_time
字段的日期时间范围。
如何获得所有Events
都没有孩子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' ]
答案 0 :(得分:1)
您可以创建一个新的query scope,以便在notInDateRange
模型中创建一个Event
范围,并在新范围内使用whereNotBetween
where clause。
在您的Event
模型类中,定义一个名为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
类的顶部。我们将使用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能够将字符串转换为日期。
如果尚未使用,请确保在Laravel中访问start_date
和end_date
列时使用Date Mutators将其转换为Carbon日期。为此,请将以下代码段添加到您的Event
模型类中:
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = [
'start_date', 'end_date'
];