Search code examples
cakephpassociationshas-manycakephp-4.x

CakePHP 4.x hasMany foreach


I'm having some difficulty getting results from a hasMany relationship in my view file. I'm not getting any errors from the debug console so I'm not sure where I'm tripping up. I think that maybe I'm not referencing correctly in the view file (I'm not really sure how to write a foreach function for this), if I'm not setting it up correctly in the table file, etc.

2 tables: "Clinicas", "Tratamientos" (services)

Goal: On a Clinic's profile page, I need to show the information for that Clinic (location, phone number, etc.) & list all of the services associated with that clinic.

ClinicasTable.php

public function initialize(array $config): void
{
    parent::initialize($config);

    $this->setTable('clinicas');
    $this->setDisplayField('name');
    $this->setPrimaryKey('clinic_id');

    $this->addBehavior('Timestamp');

    $this->hasMany('Tratamientos', [
        'foreignKey' => 'clinic_id',
        'joinType'   => 'INNER'
    ]);
}

ClinicasController.php

public function view($id = null)
{
    $clinica = $this->Clinicas->get($id, [
        'contain' => ['Tratamientos']
    ]);

    $this->set(compact('clinica'));
}

view.php

<?php foreach($clinica as $tratamiento): ?>

<?= h($clinica->tratamiento->name)?>

<?php endforeach;?>

I've had a look at the documentation for associations but can't figure out how to get to data from my tables. I could always just do an ajax query through php functions, but I'd really like to do it right using CakePHP. Any help would be much appreciated!!!


Solution

  • Even though iterating is pretty much just basic PHP, the example in the book could be a little more helpful and show iterating over and using the associated data, even though it should already give you a good idea where you data lives.

    You are obtaining a single entity (an instance of Clinica), so you cannot and should not iterate over it. What your code will do is iterate over all public properties of the entity object, which is not what you want, and won't do anything in your case, as by default entities do not have any concrete public properties.

    The data of the association will be found on the association property of the Clinica entity, which, unless specifically configured otherwise via the association's property option, is the plural, underscored, lowercased variant of the association name, so for Tratamientos that would be tratamientos.

    It should be noted that you really should stick to US english here for namings, as all the inflector magic around naming conventions is designed to work with that, names in other languages can easily cause mismatches/problems when they cannot be inflected properly!

    Long story short, you iterate the $clinica object's tratamientos property, that's where the hasMany associated data lives:

    <?php foreach($clinica->tratamientos as $tratamiento): ?>
    
    <?= h($tratamiento->name)?>
    
    <?php endforeach;?>
    

    If you are unsure about a data structure, debug it: debug($clinica)