自昨天以来,我因无法解决的要求而陷入困境。 我创建了一个站点来管理废弃的狗窝。 狗必须接种疫苗:
因此,我要从“动物”表和“ soinsveto”表中查找所有一年以上未接种疫苗的狗,或者这是自一个月以来首次接种疫苗的狗。
目标是在管理界面中显示一条警报,提示“注意,这只狗没有接种疫苗,应该早于...)
我的桌子“动物”
id | name |
我的表“ soinveto”(如果是第一种疫苗,则类型soin_id = 1,如果下一种疫苗,则延迟一个月,如果是一年,则延迟为2
id | typesoin_id | animal_id | datedusoin
动物模型
public function soinsvetos() {
return $this->hasMany(Soinsveto::class, 'animal_id');
}
soinveto模型
public function animal()
{
return $this->belongsTo(Animal::class, 'animal_id')->withTrashed();
}
我要选择:
按日期(“ datedusoin”字段)进行最后一次接种的所有动物(“食用动物”)(typesin_id = 1或2的“ soinsvetos”表)。我更喜欢用日期,因为使用者有可能在这种疾病中抓住疫苗。努力工作,以免出现“ id”危险。
然后如果“ typesoin_id”为1,我检查到今天的日期不超过一个月,如果为2,则不超过一年。
我找到了一个可行的解决方案,但完全没有经过优化:
public function compose(View $view)
{
foreach (\App\Animal::get()
->all() as $animal) {
$soins = \App\Soinsveto::with('typesoin')
->where('animal_id', $animal->id)
->where(function ($q) { /// 1 = primovaccin et 2 = vaccins annuels
$q->where('typesoin_id', '=', '2')
->orWhere('typesoin_id', '=', '1');
})
->orderBy('datedusoin', 'desc')
->get()
->first();
if ($soins) {
if ($soins->typesoin_id == '1' && $soins->datedusoin < Carbon::now()->subMonths(1)) {
$crudFieldValue = Carbon::parse($soins->getOriginal('datedusoin'))->addyear(1)->toDateString();
}
if ($soins->typesoin_id == '2' && $soins->datedusoin < Carbon::now()->subYears(1)) {
$crudFieldValue = Carbon::parse($soins->getOriginal('datedusoin'))->addyear(1)->toDateString();
}
}
$notif[] = [
'title' => $soins->typesoin->nomsoin,
'start' => $crudFieldValue,
'nomanimal' => $animal->nom,
];
}
$view->with('notif', $notif);
}
在我的版本中,所有的动物都被加载,这会产生大量的sql请求。 我找不到任何解决方案来实现这一目标。我做了很多尝试,但无法在单个优化查询中将所有内容汇总在一起
答案 0 :(得分:0)
在我对问题的评论之后,建议您将foreach语句重写为以下代码。它使用with
函数渴望在所有动物中加载soinsvetos
关系,这样您就不会遇到N + 1问题。
foreach (\App\Animal::with('soinsvetos')->get() as $animal) {
$soins = $animal->soinsvetos
->filter(function ($soinsveto) {
/// 1 = primovaccin et 2 = vaccins annuels
return $soinsveto->typesoin_id == 1 || $soinsveto->typesoin_id == 2;
})
->sortBy('datedusoin', 'desc')
->first();
if ($soins) {
if ($soins->typesoin_id == '1' && $soins->datedusoin < Carbon::now()->subMonths(1)) {
$crudFieldValue = Carbon::parse($soins->getOriginal('datedusoin'))->addyear(1)->toDateString();
}
if ($soins->typesoin_id == '2' && $soins->datedusoin < Carbon::now()->subYears(1)) {
$crudFieldValue = Carbon::parse($soins->getOriginal('datedusoin'))->addyear(1)->toDateString();
}
}
$notif[] = [
'title' => $soins->typesoin->nomsoin,
'start' => $crudFieldValue,
'nomanimal' => $animal->nom,
];
}