We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Checking for the existence of a child model in volt causes "Call to a member function on a non-object"

I have two models, PatientList and CodeList. Several fields in PatientList map to CodeList and those fields can sometimes be null. From PatientList initialize():

 public function initialize(){
    parent::initialize();
    $this->hasOne("study_status","dbsr\Models\CodeList","id",array("alias"=>"StudyStatusChild"));
    $this->hasOne("followup_status","dbsr\Models\CodeList","id",array("alias"=>"FollowupStatusChild"));
  }

Then inside the volt I have:

        <td>{% if patient.getStudyStatus() == '' %} &nbsp; {% else %} {{ patient.getStudyStatusChild().getValue('codelist_value')}}{% endif%}</td>
        <td>{% if patient.getFollowupStatus() == ''  %} &nbsp; {% else %}  {{ patient.getFollowupStatusChild().getValue('codelist_value')}} {%endif%}</td>

In cases where getFollowupStatus() or getStudyStatus() are blank, the code inside the {% else %} appears to still be evaluated, and the object is null so it throws an error. How can I display the contents of child records in the case that they are sometimes blank?

It seems that condition in if-statement return non false value but patient model has not child object by this value. May be structural integrity of your table is broken.



40.7k

That is not the problem. This page contains a Paginator, and there is an area where users can filter which rows are displayed in the results.

$query = Criteria::fromInput($this->di,'dbsr\Models\PatientList',$this->request->get());

I also added a date filter, but it's a range, so I can't just use the same field names, because there is a start and end date. So I did this, after creating the query:

      if($this->request->get("appt_start_date") ){
    $query->andWhere('apt_date >= :appt_start_date:',array('appt_start_date'=>$this->request->get('appt_start_date','string')));
      }

      if($this->request->get("appt_end_date") ){
    $query->andWhere('apt_date <= :appt_end_date:',array('appt_end_date'=>$this->request->get('appt_end_date','string')));
      }

If those lines are not called, the page renders properly, even in cases with rows where the child object is blank. If I try and do a date filter it throws up on the rows with no child object. Why would that matter?



40.7k

I think it has something to do with hydration mode. When I do addWhere it isn't hydrating the child records in the same way as when I don't



40.7k

Argh! OK - it was a row that had the foreign key = 0 instead of null. Updating it to null fixed the problem. You were correct!