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

Accessing model relationships in volt via paginator

I have two models, PtsPerStudy and SaeReport:

public class SaeReport extends Phalcon\Mvc\Model{
    public function initialize(){
        $this->belongsTo("ae_id","PtsPerStudy","id");
    }
    ...
}

public class PtsPerStudy extends Phalcon\Mvc\Model{
    public function initialize(){
        $this->hasMany('id','SaeReport','ae_id');
    }
    ...
}

Each SaeReport has one PtsPerStudy record and a PtsPerStudy record can have many SaeReport rows. Here is the code from the controller:

 public function indexAction($id){

      $numberPage = 1;

      $identity=$this->auth->getIdentity();
      $query = Criteria::fromInput($this->di,'SaeReport',$this->request->getPost());

      $this->persistent->searchParams = $query->getParams();
      $numberPage = $this->request->getQuery('page','int');

      $parameters = array();
      if($this->persistent->searchParams){
    $parameters = $this->persistent->searchParams;
      }else{
    $parameters = "study_id = ".$id ;
      }

      $saereports = SaeReport::find($parameters);

      $paginator = new Paginator(array("data"=>$saereports,"limit"=>10,"page"=>$numberPage));

      $this->view->page = $paginator->getPaginate();

      $mystudy = Studies::findFirstByPkStudy($id);

      $this->view->mystudy=$mystudy;

  }

And I see this error, once per row to be displayed, in /var/log/httpd/error_log:

[Tue Oct 21 11:37:05 2014] [error] [client 156.145.229.210] PHP Notice:  Access to undefined property SaeReport::PtsPerStudy in /var/www/html/dsmc/app/cache/_var_www_html_dsmc_app_views_saereport_index.volt.php on line 23, referer: <url>

Is this something that I am doing wrong or is there a bug in the volt template engine? I would think that it should be accessing it like SaeReport->PtsPerStudy not SaeReport::PtsPerStudy, no?



5.7k
edited Oct '14

When calling related models, prepend the related model name with "get".

So instead of:

SaeReport->PtsPerStudy()

Try using:

SaeReport->getPtsPerStudy()


40.7k

Yes that was a typo, thank you. The error is being thrown in the volt, not the controller.

{% for item in page.items %}

        <tr>
        <td>{{item.PtsPerStudy.getName()  }}</td>
        <TD> {{link_to("SAEReport/viewlist/" ~ mystudy.getPkStudy() ~ "/" ~ item.getId()," View","class":"btn btn-primary") }}</TD>
        </tr>

{% if loop.last %}

So item is the SaeReport items in the paginator and I want to access the PtsPerStudy row associated with each SaeReport row that I am displaying in the paginator.



5.7k

The same rule still applies in the volt template files. In the case of your newest example, try this:

{% for item in page.items %}

        <tr>
        <td>{{item.getPtsPerStudy().getName()  }}</td>
        <TD> {{link_to("SAEReport/viewlist/" ~ mystudy.getPkStudy() ~ "/" ~ item.getId()," View","class":"btn btn-primary") }}</TD>
        </tr>

{% if loop.last %}

When you acess the paginated items in a template, you are still referencing the objects (Phalcon\Mvc\Model\Resultset\Simple) unless you change the hydration option. Instead of "->", you'll just use a period.



5.7k

One thing I forgot to add was that when you refer to methods of realted Models in volt (i.e. items.getPtsPerStudy().getName()), if the related result does not exist, it will throw an exception that it can not find, in your case, "getName()" of an undefined object since "getPtsPerStudy()" will not return an object.

I'm not entirely sure on the best way of doing this but here is what I've done in the past:

{% for item in page.items %}
        {% set PtsPerStudy = item.getPtsPerStudy() %}
        <tr>
        <td>{{ PtsPerStudy ? PtsPerStudy.getName() : '-'  }}</td>
        <TD> {{link_to("SAEReport/viewlist/" ~ mystudy.getPkStudy() ~ "/" ~ item.getId()," View","class":"btn btn-primary") }}</TD>
        </tr>

{% if loop.last %}


40.7k
The method "getPtsPerStudy" doesn't exist on model "SaeReport"

(



5.7k
edited Oct '14

Hmm, the only time I've come across that error was when I had my relationship settings messed up in the models.

Are your models setup with namespaces?

Also, could you post up part of those table schemas?



40.7k

Yes my models are set up with namespaces, I was removing them for clarity, but I can include them.

CREATE TABLE `sae_report` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `study_id` int(11) DEFAULT NULL,
  `sponsor` varchar(45) DEFAULT NULL,
  `overall_pi` varchar(45) DEFAULT NULL,
  `is_up` varchar(1) DEFAULT NULL,
  `report_type` varchar(1) DEFAULT NULL,
  `date_pi_informed` date DEFAULT NULL,
  `date_of_report` date DEFAULT NULL,
  `date_of_onset` date DEFAULT NULL,
  `date_resolved` date DEFAULT NULL,
  `ae_id` varchar(200) DEFAULT NULL,
  `death` int(11) DEFAULT NULL,
  `lifethreat` int(11) DEFAULT NULL,
  `hosp` int(11) DEFAULT NULL,
  `disability_incapacity` int(11) DEFAULT NULL,
  `congentical_abn` int(11) DEFAULT NULL,
  `otherwise_serious` int(11) DEFAULT NULL,
  `causality` varchar(15) DEFAULT NULL,
  `expectedness` varchar(15) DEFAULT NULL,
  `brief_description` text,
  `diagnosis` text,
  `if_recovered_date` date DEFAULT NULL,
  `if_fatal_date` date DEFAULT NULL,
  `cause_of_death` varchar(255) DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  `outcome_fatal` int(11) DEFAULT NULL,
  `outcome_ongoing` int(11) DEFAULT NULL,
  `outcome_recovered_with` int(11) DEFAULT NULL,
  `outcome_recovered` varchar(45) DEFAULT NULL,
  `is_deleted` int(11) DEFAULT NULL,
  `submitted_date` varchar(45) DEFAULT NULL,
  `outcome` text,
  `crc_name` varchar(45) DEFAULT NULL,
  `crc_uni` varchar(45) DEFAULT NULL,
  `crc_fax` varchar(45) DEFAULT NULL,
  `crc_phone` varchar(45) DEFAULT NULL,
  `pi_fax` varchar(45) DEFAULT NULL,
  `pi_phone` varchar(45) DEFAULT NULL,
  `pi_name` varchar(45) DEFAULT NULL,
  `pi_uni` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1532 DEFAULT CHARSET=utf8;

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `pts_per_study` AS select distinct `events`.`patient_study_id` AS `patient_study_id`,`events`.`MRN` AS `mrn`,`events`.`pk_study` AS `pk_study`,`events`.`pt_age` AS `pt_age`,`events`.`sex` AS `sex` from `events`;

Is it maybe because PtsPerStudy is actually based on a database view and not a table? The phalcon dev tools happily created a model for it from command line...

So ae_id in the table sae_report is a foreign key to id from the view pts_per_study



5.7k
Accepted
answer

There could be a few things.

I don't see the id column in the view (ptsperstudy) but another thing you should look at when creating your relationships in the models is including the namespaces as shows here: https://docs.phalcon.io/en/latest/reference/models.html#cascade-restrict-actions



40.7k

Wow I am slow today. Thank you I forgot to include ID in the select...



5.7k

Glad I could help :-)