I have relation method for a model which has a comparison on a property(created_at) of the model itself. Where I want to compare the created_at date of the 'Appointment' model with the created_at of the 'Treatment'. I only want a 'Treatment' if its 'created_at' date is later than that of the 'Appointment'
AppointmentController.php
public function index(): JsonResource
{
$users = User::with([
'appointment' => function ($query) {
$query->with(['appointment_events']);
},
])
->active()
->get();
return UserResource::collection($users);
}
Appointment.php
public function appointment_events(): HasMany
{
return $this->hasMany(AppointmentEvent::class)
->with([
'customer' => function ($query) {
$query->with([
'section' => function ($subquery) {
$subquery
->with([
'advice',
'treatment' => function ($subquery) {
$subquery->where('created_at', '>', blank); //How can I get the model's created_at date.
},
]);
},
]);
},
]);
}
Is there a way to do this?
CodePudding user response:
If I understand yours relations are
User ->HasManyAppointments ->HasManyAppointmentsEvents.
You can access quite directly to appointments events data from a user
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get all of the appointment_events for the user.
*/
public function appointment_events()
{
return $this->hasManyThrough(Appointment::class, AppointmentEvent::class);
}
}
From Laravel Doc: Has Many Through
So you can query
$collection = User::with(['appointments','appointment_events'])->where()->get();
which give you all appointments and related appointment_events on a particular user. and you can tap on that collection or filter or whatever business logic you want.
CodePudding user response:
I think you should move the query to a scope on Appointment model and keep the relationship definition simple.
Note: Below assumes table names and column names as per standard Laravel conventions. If you have different convention, please modify the table names and column names accordingly.
class Appointment extends Model
{
public function scopeWithFutureTreatments($query)
{
return $query->with([
'appointment_events' => function($query) {
$query->with([
'customers' => function($query) {
$query->with([
'section' => function($query) {
$query->with([
'advice',
'treatment' => function($query){
$query->join('sections', 'section.id', '=', 'treatments.section_id')
->join('customers', 'customers.id', '=', 'sections.customer_id')
->join('appointment_events', 'appointment_events.id', '=', 'customer.appointment_events_id')
->join('appointments', 'appointments.id', '=', 'appointment_events.appointment_id')
->whereColumn('treatments.created_at', '>', 'appointments.created_at')
->select('treatments.*')
}
]);
}
]);
}
]);
}
]);
}
public function appointment_events(): HasMany
{
return $this->hasMany(AppointmentEvent::class);
}
}
Then in AppointmentController the following should get you the desired results
public function index(): JsonResource
{
$users = User::with([
'appointment' => function ($query) {
$query->withFutureTreatments();
},
])
->active()
->get();
return UserResource::collection($users);
}