我有两个表:患者和预约(预约)。有一个一对多的关系,病人:appt。我的目标是返回患者集合,并从该关系中返回患者的上次约会和下一次约会的日期。
我得到不一致的结果。我已经播种了数据,以便每个患者在过去和将来都有约会,但是当我使用Eloquent进行查询时(请参见下面的“控制器”),我不会得到“ lastappt”。如果我修改查询以按患者的ID进行搜索,我会得到lastappt。
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);
}
}
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();
任何帮助将不胜感激,谢谢您!
答案 0 :(得分:0)
您可以使用:
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
可能为空,因此您可以使用optional
助手:
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();