0
\$\begingroup\$

is there a more elegant way to do what the code below does without use "foreach"? I am trying to load answers from questions but only the answers that contains a direct relation with an Appointment

public function show(Request $request, Patient $patient)
{
 $user = $request->user();
 $appointments = Appointment::with('forms.questions')
 ->where('patient_id', $patient->id)
 ->where('user_id', $user->id)
 ->get();
 foreach ($appointments as $appointment) {
 foreach ($appointment->forms as $form) {
 foreach ($form->questions as $question) {
 $question->load(['answers' => function ($q) use ($appointment) {
 $q->where('appointment_id', $appointment->id);
 }]);
 }
 }
 }
 return view('patients.show', compact('patient', 'appointments'));
}

I tried with no luck

public function show(Request $request, Patient $patient)
{
 $user = $request->user();
 $appointments = Appointment::with(['forms.questions.answers' => function ($query) {
 $query->where('answers.appointment_id', 'appointments.id')
 }])
 ->where('patient_id', $patient->id)
 ->where('user_id', $user->id)
 ->get();
 return view('patients.show', compact('patient', 'appointments'));
}

EDIT: Below are the relationships

  • Form

    • questions (hasMany)
    • appointments (belongsToMany)
  • Question

    • answers (hasMany)
  • Answer

    • question (belongsTo)
    • appointment (belongsTo)
  • Appointment

    • answers (hasMany)
    • forms (belongsToMany)
    • patient (hasOne)
    • user (hasOne)
  • Patient

    • user (BelongsTo)
    • appointments (hasMany)
  • User

    • appointments (hasMany)

A table called appointment_form is a pivot table for appointments and forms table.

asked Oct 11, 2021 at 18:01
\$\endgroup\$
3
  • \$\begingroup\$ Ahoy! Please edit to explain the relationships more thoroughly. Is there a one-to-many relationship between questions and answers? and also does an answer belong to an appointment, separately from through the question or using a belongsToThrough relationship? You could consider using the format from this post \$\endgroup\$ Commented Oct 12, 2021 at 15:30
  • \$\begingroup\$ you can add a different relation or a scope within questions model or consider using a builder class instead. Re builder class, dont know the scale of your app - but, ask yourself a question - what will happen you need to change patient_id to something different? \$\endgroup\$ Commented Oct 14, 2021 at 20:47
  • 1
    \$\begingroup\$ Why do answers belongTo appointments? Shouldn't it be just answer->question->form->appointment? \$\endgroup\$ Commented Oct 17, 2021 at 14:41

1 Answer 1

2
\$\begingroup\$

The solution below comes after rethinking the actual implementation of the business logic.

Since one Appointment can have zero or many Answers, I do not need to relate Appointments with a Form.

All I have to do is only save Answers with the reference of Question and Appointment.

And on appointments.show when I need only the Forms (with Questions) that have Answers related with current Appointment just do:


$fromAppointment = function ($builder) use ($appointment) {
 $builder->where('appointment_id', $appointment->id);
};
$forms = Form::whereHas('questions.answers', $fromAppointment)
 ->with(['questions.answers' => $fromAppointment])
 ->get();

And on appointments.edit when I need all the Forms even those that do not have Answers, all I need to do is:

$forms = Form::with(['questions.options', 'questions.answers' => function ($builder) use ($appointment) {
 $builder->where('appointment_id', $appointment->id);
])
->get();

And the relationship between Appointments and Forms was dropped.

Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
answered Oct 18, 2021 at 20:57
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.