I am trying to improve at laravel, the story here is that I have customers, customers can have appointments and users create appointments for the customers.
Visit model:
class Visit extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'customer_id',
'report',
'appointment_date',
'appointment_time',
];
protected $dates = ['appointment_date'];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
Customer model:
class Customer extends Model
{
use HasFactory;
protected $fillable = [
'name',
'city',
'address',
'email_address',
'phone_number',
];
I have a script that checks if the customer should have a new appointment (this happens if there is no new appointment in the future and when the last appointment is longer than 5 months ago or there is no appointment yet:
$customers = Customer::get();
foreach ($customers as $customer) {
$Newvisit = $customer->visits()->whereInFuture()->first();
// continue if the customer already has an appointment planned in the future
if ($Newvisit !== null) {
continue;
}
// This also retrieves visits with null appointment date, this is neccesary for appointments that are not schedulded but already planned
$lastVisit = $customer->visits()->OrderBy('appointment_date', 'desc')->first();
// Customer has no visits yet
if ($lastVisit === null) {
$this->createNewAppointment($customer);
continue;
}
$lastVisitDate = new Carbon($lastVisit->appointment_date);
// Last appointment for customer is longer than .. months ago
if ($lastVisitDate->diffInMonths() > $this->argument('months')) {
$this->createNewAppointment($customer);
continue;
}
}
Is there a way to use eager loading to only run 1 query? or is this impossible since I need to retrieve a new visit and last visit
There is a relationship in customer model to get visits.
public function visits()
{
return $this->hasMany(Visit::class);
}
Then you can fetch customers data as $customers = Customer::with('visits')->get();
Or you can order visits like this -
$customers = Customer::with(['visits' => function ($query) {
$query->orderBy('appointmemt_date', 'desc');
}])->get();
Then $customer->visits->first(); may give you inkling whether it is New visit or Last Visit.