我尝试以下操作:我有两个与1xN关系相关的模型(Pub和Schedule),如下所示:
const inputRange = [1,2,3,4,5,6,7,8,9,10]
if(inputRange.includes(parseInt(input)))
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function pubSchedules()
{
return $this->hasMany(Schedule::class);
}
表格时间表包含以下字段:
id | pub_id | week_day | opening_time | closing_time |
我使用以下函数来了解当前(或不)打开一个酒吧:
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function pub()
{
return $this->belongsTo(Pub::class);
}
在我的PubController中我喜欢,当选项"过滤开放酒吧"已选择/**
* @return bool
*/
public function isPubCurrentlyOpen()
{
$schedules = Schedule::where([
['pub_id', $this->id ],
['week_day', Carbon::now()->dayOfWeek],
])->get();
foreach ($schedules as $schedule){
$isOpen[] =
Carbon::now('Europe/Madrid')->between(
Carbon::now('Europe/Madrid')->setTimeFromTimeString($schedule->opening_time),
Carbon::now('Europe/Madrid')->setTimeFromTimeString($schedule->closing_time)
);
}
if(in_array(true, $isOpen)){
return true;
//return "Pub Opened";
}
return false;
//return "Pub Closed";
}
,仅显示已打开的酒吧if($request->openPubs == 1)
。
了解模型之间的关系,我该怎么做?
我正在寻找类似的东西:
isOpen ==true
你能帮助我吗?
非常感谢!
答案 0 :(得分:1)
我不完全明白你是如何努力实现这一点的,但它应该是这样的
$pubs = Pub::with(['pubSchedules' => function ($query) {
$query->where('opening_time', '>' ,Carbon::now()) // make sure it's currently open
->where('closing_time', '<' ,Carbon::now()) // make sure that it's not finished already
->where('week_day', '==' ,Carbon::now()->dayOfWeek) // make sure it's today
}])->find($id);
// to get if pub is currently
if($pub->pubSchedules->count()){
//
}
you can put this code in the model (Pub) and make some changes
if you already have the object you can do this (Add it to model)
public function isPubOpen()
{
$this->load(['pubSchedules' =>
// same code in other method
]);
return (bool) $this->pubSchedules->count();
}
答案 1 :(得分:1)
您可以使用“whereHas”
执行此操作$openPubs = Pub::whereHas('schedule', function ($query) {
$query->where('week_day', Carbon::now()->dayOfWeek);
$query->whereRaw(
"'".Carbon::now('Europe/Madrid')->format("H:i:s")."' BETWEEN opening_time AND closing_time"
);
})->get();
这假设您的开放时间和结束时间是适当的时间格式而不是字符串(尽管字符串在24小时格式中也能正常工作)。
使用示波器,您可能会获得类似于您所寻找的内容,例如:
public function scopeFilterBy($query, $filter = null) {
if ($filter == "isOpen") {
$query->whereHas('schedule', function ($query) {
$query->where('week_day', Carbon::now()->dayOfWeek);
$query->whereRaw(
"'".Carbon::now('Europe/Madrid')->format("H:i:s")."' BETWEEN opening_time AND closing_time"
);
});
}
return $query; //Not sure if this is needed
}
然后你可以这样做:
Pub::filterBy($request->openPubs ? "isOpen" : null)->get();
答案 2 :(得分:0)
对于小表,您可以为每个元素调用函数isPubCurrentlyOpen
。
为此,您需要更改函数以将pub_id作为参数接收:
public function isPubCurrentlyOpen($pub_id)
{
$schedules = Schedule::where([
['pub_id', $pub_id ],
['week_day', Carbon::now()->dayOfWeek],
])->get();
foreach ($schedules as $schedule){
$isOpen[] =
Carbon::now('Europe/Madrid')->between(
Carbon::now('Europe/Madrid')->setTimeFromTimeString($schedule->opening_time),
Carbon::now('Europe/Madrid')->setTimeFromTimeString($schedule->closing_time)
);
}
if(in_array(true, $isOpen)){
return true;
//return "Pub Opened";
}
return false;
//return "Pub Closed";
}
并查询数据:
if($request->openPubs == 1)
{
// assuming $pubs is a collection instance
$pubs = $pubs->filter(function($a){
return $this->isPubCurrentlyOpen($a->id);
})
}
答案 3 :(得分:0)
Eloquent中有一个名为Eager Loading的功能。 Eloquent ORM提供了一种简单的语法来查询与此特定Pub相关的所有Schedules,如下所述:
$pubIsOpen= $pub->schedules()
->where([
['week_day', Carbon::now()->dayOfWeek],
['opening_time' , '<' , Carbon::now('Europe/Madrid')],
['closing_time' , '>' , Carbon::now('Europe/Madrid')]
])
->count();
if($openPubCount > 0){
//PUB is open
}else{
//PUB is closed
}
答案 4 :(得分:0)
如果将来有人帮助我发布我的解决方案,感谢@apokryfos:
/**
* @param $pubs
* @return mixed
*/
public static function isPubCurrentlyOpen($pubs)
{
$pubs->whereHas( 'pubSchedules', function ($pubs) {
$pubs->where( 'week_day', Carbon::now()->dayOfWeek )
->whereRaw(
"'" . Carbon::now( 'Europe/Madrid' )->format( "H:i:s" ) . "' BETWEEN opening_time AND closing_time"
);
} );
return $pubs;
}
/**
* @param GetPubRequest $request
* @return ApiResponse
*/
public function getPubs(GetPubRequest $request)
{
$orderBy = 'id';
$order = 'asc';
$pubs = Pub::withDistance();
............
if($request->openPubs == 1)
{
$pubs = Pub::isPubCurrentlyOpen($pubs);
}
return $this->response(PubProfileResource::collection($pubs->orderBy($orderBy, $order)->paginate()));
}