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

SQL Relationship Bugs

I got lot of relationships problems.

I started an issue on github during the time the "start a Discussion" button didn't work.

https://github.com/phalcon/cphalcon/issues/13191

As said in the issue.

If I put full class name on both class arg of hasManyToMany function, the intermediate table is not filled, with no error messages. If I don't put full class name, I can't save or can't get because the ORM can't load the model. And even if I put the full class name the getter method just doesn't work and always return NULL (weird, cause when I var_dump my instance, I can see some references to my relation ChapterTeams).

The whole Relationship seems broken right now.



3.8k
Accepted
answer
edited Dec '17

Use the Alias option to use the implicit function.

    // some relationships example
    public function initialize() {
        $this->hasMany('id', 'Project\\Models\\ArticleTopic', 'article_id', array('alias' => 'TopicsNode'));
        $this->hasManyToMany('id', 'Project\\Models\\ArticleTopic', 'article_id', 'topic_id', 'Project\\Models\\Topic', 'id', array('alias' => 'Topics'));
        $this->belongsTo('user_id', 'Project\\Models\\User', 'id', array('alias' => 'User'));
        $this->hasMany('id', 'Project\\Models\\Comment', 'article_id', array('alias' => 'Comments'));
    }

    // implicit way example
    $article->getTopics();
    $article->getUser();
    $article->getComments();


8.2k

Thanks, it seems to be working. I didn't see that opltions in the docs, so thanks very much.

edited Dec '17

You are right, the information somehow disapeared. However I've found a section where you can see an example: Models Relationships - Conditionals

I've been realizing that I absolutely need to specify the Alias option when using namespaces into my models.

Oh wait, found it in the olddocs website: https://olddocs.phalcon.io/en/latest/reference/model-relationships.html#aliasing-relationships

MySQL

SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/log/mysql/debug.log';

PHP

class RobotsParts extends Phalcon\Mvc\Model
{
    public function initialize()
    {
        $this->belongsTo(
            'parts_id',
            Parts::class,
            'id',
            [
                'alias' => 'parts',
            ]
        );

        $this->belongsTo(
            'robots_id',
            Robots::class,
            'id'
        );
    }
}

class Robots extends Phalcon\Mvc\Model
{
    public function initialize()
    {
        $this->hasManyToMany(
            'id',
            RobotsParts::class,
            'robots_id',
            'parts_id',
            'Parts',
            'id'
        );
    }
}

class Parts extends Phalcon\Mvc\Model
{
    public function initialize()
    {
        $this->hasMany(
            'id',
            RobotsParts::class,
            'parts_id'
        );
    }
}

$di = new Phalcon\Di\FactoryDefault();

$di->set('db', function () {
    return new Phalcon\Db\Adapter\Pdo\Mysql([
        "host"     => "127.0.0.1",
        "dbname"   => "phalcon_test",
        "port"     => 3306,
        "username" => "root",
        "password" => "",
    ]);
});

$robot = new Robots([
    'name'     => 'The Tachikomas II',
    'type'     => 'mechanical',
    'year'     => 1989,
    'datetime' => '1989-01-01 00:00:00',
    'text'     => 'Ghost in the Shell',
]);

var_dump($robot->getParts()->count());

$parts = [
    new Parts(['name' => 'Leg-3']),
    new Parts(['name' => 'Hand-3']),
    new Parts(['name' => 'Head-3']),
    new Parts(['name' => 'Eye-3']),
    new Parts(['name' => 'Antenna-3']),
];

$robot->parts = $parts;
var_dump($robot->getParts()->count());

$robot->save();

var_dump($robot->getParts()->count());
$id = $robot->id;

unset($robot);

$robot = Robots::findFirst($id);
var_dump($robot->getParts()->count());

Output

int(0)
int(0)
int(5)
int(5)
cat /var/log/mysql/debug.log | grep "INSERT\|TRANSACTION\|COMMIT" | awk -F'Query' '{print $2}'
    START TRANSACTION
    INSERT INTO `robots` (`name`, `type`, `year`, `datetime`, `deleted`, `text`) VALUES ('The Tachikomas II', 'mechanical', 1989, '1989-01-01 00:00:00', DEFAULT, 'Ghost in the Shell')
    INSERT INTO `parts` (`name`) VALUES ('Leg-3')
    INSERT INTO `robots_parts` (`robots_id`, `parts_id`) VALUES ('43', '188')
    INSERT INTO `parts` (`name`) VALUES ('Hand-3')
    INSERT INTO `robots_parts` (`robots_id`, `parts_id`) VALUES ('43', '189')
    INSERT INTO `parts` (`name`) VALUES ('Head-3')
    INSERT INTO `robots_parts` (`robots_id`, `parts_id`) VALUES ('43', '190')
    INSERT INTO `parts` (`name`) VALUES ('Eye-3')
    INSERT INTO `robots_parts` (`robots_id`, `parts_id`) VALUES ('43', '191')
    INSERT INTO `parts` (`name`) VALUES ('Antenna-3')
    INSERT INTO `robots_parts` (`robots_id`, `parts_id`) VALUES ('43', '192')
    COMMIT