php - Laravel 5.6 - 使用 Eloquent 在相关表的日期时间字段中返回最新日期的问题
问题描述
我有两个表:患者和 appts(约会)。有一个一对多的关系患者:appt。我的目标是返回一组患者,并从关系中返回患者上次和下次约会的日期。
问题/问题
我得到不一致的结果。我已经播种了数据,以便每个患者在过去和将来都有约会,但是当我使用 Eloquent 进行查询时(请参阅下面的“控制器”),我没有得到“lastappt”。如果我修改查询以按患者 ID 进行搜索,我会得到最后一个应用程序。
“病人”模型
class Patient extends Model
{
...
public function appts()
{
return $this->hasMany('App\Models\Appt');
}
public function lastappt()
{
$now = Carbon::now();
return $this
->hasMany('App\Models\Appt')
->select(['id', 'patient_id', 'appt_date_time'])
->where('appt_date_time', '<', $now)
->orderBy('appt_date_time', 'desc')
->take(1);
}
public function nextappt()
{
$now = Carbon::now();
return $this
->hasMany('App\Models\Appt')
->select(['id', 'patient_id', 'appt_date_time'])
->where('appt_date_time', '>', $now)
->orderBy('appt_date_time', 'asc')
->take(1);
}
}
“Appts”迁移
Schema::create('appts', function (Blueprint $table) {
$table->increments('id');
$table->integer('patient_id')->unsigned();
$table->integer('hospital_id')->unsigned();
...
$table->datetime('appt_date_time')->nullable();
...
$table->timestamps();
$table->index(['patient_id', 'hospital_id', 'appt_date_time']);
$table->foreign('patient_id')
->references('id')->on('patients')
->onDelete('cascade');
});
控制器
$currPatientCollection = Patient::with('lastappt')
->with('nextappt')
->where('office_id', $user->office_id)
->where('current_patient', true)
->orderBy('last_name')
->orderBy('first_name')
->get();
这仅返回一个 nextappt,即使数据库过去有 appts。但是,以下查询有效(正如我“预期的”),并返回带有 lastappt 和 nextappt 的患者记录。
$currPatientCollection = Patient::with('lastappt')
->with('nextappt')
->where('id', 1)
->where('current_patient', true)
->orderBy('last_name')
->orderBy('first_name')
->get();
任何帮助将不胜感激,并提前感谢您!
解决方案
您可以使用:
public function lastappt()
{
$now = Carbon::now();
return $this
->hasOne('App\Models\Appt')
->select(['id', 'patient_id', 'appt_date_time'])
->where('appt_date_time', '<', $now->toDateTimeString())
->orderBy('appt_date_time', 'desc')
->groupBy('patient_id');
}
public function nextappt()
{
$now = Carbon::now();
return $this
->hasOne('App\Models\Appt')
->select(['id', 'patient_id', 'appt_date_time'])
->where('appt_date_time', '>', $now->toDateTimeString())
->orderBy('appt_date_time', 'asc')
->groupBy('patient_id');
}
现在您可以使用:
$patient = Patient::find($someId);
echo $patient->lastappt->appt_date_time;
echo $patient->nextappt->appt_date_time;
当然,在上面的 3 行中,您应该假设lastappt
或nextappt
可能为 null,以便您可以使用optional
helper:
echo optional($patient->lastappt)->appt_date_time;
echo optional($patient->nextappt)->appt_date_time;
当然,当您有多个患者时,您应该急切地加载这些关系以避免 n+1 查询问题:
$patients = Patient::with('lastappt', 'nextappt')->whereIn('id', $someIds)->get();
推荐阅读
- webpack - ScriptExternalLoadError:加载脚本失败。vue-cli@5.0.0-rc.0
- deep-learning - 在 torch.nn.Sequential 中重新排列神经网络层
- java - 鉴于我有构造函数,如何从类中调用方法?
- php - 如何在我的 html/php 表单中添加更多字段
- maven - Dockerfile 上的多模块 Maven 项目的问题
- wordpress - WooCommerce 产品网格(重新排列产品详细信息)
- python - 使用 csv 文件中现有的 url 列表抓取酒店信息
- visual-studio-code - HTML标签的VS代码格式问题
- c# - Unity 3d:如何通过单击在 UI 工具包上设计的 UI 中的按钮在我的角色上显示动画?
- android - Jetpack 数据存储实现