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

Get the values from related tables on the third level with multiple records

Models

<?php
namespace Zzz\Models;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Relation;
use Phalcon\Mvc\Model\Validator\Uniqueness;

class Rules extends Model
{

    /**
     *
     * @var integer
     */
    public $id;

    /**
     *
     * @var integer
     */
    public $time;

    public function initialize()
    {
        $this->belongsTo('time', 'Zzz\Models\AliasesTime', 'id', array(
            'alias' => 'aliasestime'
        ));
    }

}

namespace Zzz\Models;

use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Relation;
use Phalcon\Mvc\Model\Validator\Uniqueness;

class AliasesTime extends Model
{

    /**
     *
     * @var integer
     */
    public $id;

    /**
     *
     * @var string
     */
    public $name;

    public function initialize()
    {
        $this->hasMany("id", "Zzz\Models\AliasesTimeContent", "aliastimeId", array(
            "alias" => "aliasestimecontent",
            "foreignKey" => array(
                "action" => Relation::ACTION_CASCADE
            )
        ));
        $this->hasMany("id", "Zzz\Models\Rules", "ruletime", array(
            "alias" => "rules",
            "foreignKey" => array(
                "message" => "The alias cannot be deleted because other internet policy rule are using it"
            )
        ));
    }

}

namespace Zzz\Models;

use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Relation;

class AliasesTimeContent extends Model
{

    /**
     *
     * @var integer
     */
    public $id;

    /**
     *
     * @var string
     */
    public $starttime;

    /**
     *
     * @var string
     */
    public $endtime;

    /**
     *
     * @var integer
     */
    public $aliastimeId;

    public function initialize()
    {
        $this->belongsTo("aliastimeId", "Zzz\Models\AliasesTime", "id", array(
            "alias" => "aliasestime",
            "foreignKey" => true
        ));
    }
}

Code

....
$rules = Rules::find();
if ($rules) {
    $timeAlias = array();
    foreach ($rules as $policy) {

# Here I am required to conduct a new forearch
# For I can not access the table values AliasesTimeContent directly by model
# When the find returns multiple results
# $policy->aliasestime->aliasestimecontent->starttime

        foreach ($policy->aliasestime->aliasestimecontent as $content) {
            echo $content->id;
            echo $content->starttime;
            echo $content->endtime;
            echo $content->aliastimeId;
        }
    }
}
...

The code is works, but is logging warnings in the Apache error log to " foreach ($policy->aliasestime->aliasestimecontent as $content) {"

[Fri Jan 23 16: 16: 54.857380 2015] [: error] [pid 27759] [client 192.168.122.1:41581] PHP Warning: Invalid argument supplied for foreach ()

Perhaps there is a proper way to get these values using the model or some method of the framework, but I could not find in the documentation. Has anyone had to do that? Any tips?



33.8k

Maybe:

$aliasestime = $policy->aliasestime;

foreach ($aliasestime->aliasestimecontent as $content)
{
    ...
}


2.1k
 $this->hasMany("id", "Zzz\Models\Rules", "ruletime", array( // <<
            "alias" => "rules",
            "foreignKey" => array(
                "message" => "The alias cannot be deleted because other internet policy rule are using it"
            )
        ));

        public $ruletime; // << ??


5.7k
edited Jan '15

I might just be tired, but it doesn't seem like the relationships make sense.

First, I don't see where there is a property named "$ruletime" in the Rules model. I just see $time.

Second, if Rules $time belongs to AliasesTime $id, and AliasTime $id links to (hasMany) AliasesTimeContent $aliastimeId, doesn't that mean that Rules $time also belongs to AliasesTimeContent $aliastimeId (or maybe AliasesTimeContent $aliastimeId belongsTo Rules $time)?

Sorry, I renamed the fields to get simpler.

class Rules extends Model
{
    /**
     *
     * @var integer
     */
    public $id;

    /**
     *
     * @var integer
     */
    public $ruletime;

    public function initialize()
    {
        $this->belongsTo('ruletime', 'Zzz\Models\AliasesTime', 'id', array(
            'alias' => 'aliasestime'
        ));
    }
}

I believe that the relationship is correct. By posting the question I removed fields and tried to simplify to a better understanding. But I ended up leaving one of the changed relations. AliasTime is a type of content, the content thereof is registered in the AliasTimeContent. How AliasTime is a type of content, I can use it in various Rules.

I might just be tired, but it doesn't seem like the relationships make sense.

First, I don't see where there is a property named "$ruletime" in the Rules model. I just see $time.

Second, if Rules $time belongs to AliasesTime $id, and AliasTime $id links to (hasMany) AliasesTimeContent $aliastimeId, doesn't that mean that Rules $time also belongs to AliasesTimeContent $aliastimeId (or maybe AliasesTimeContent $aliastimeId belongsTo Rules $time)?



4.1k
Accepted
answer

I created a separate table to store the AliasTime used by the Rules. And created a standard for the alias naming because they had duplicate alias in models.