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

Can't get Model relations to work.

Hi

If I have a Model t1:

<?php
class t1 extends Phalcon\Mvc\Model
{
    public $id;
    public $t2_id;

    public function initialize()
    {
        $this->setSource('t1');
        $this->hasOne('t2_id', 't2', 'id');
    }
}

and a Model t2:

<?php
class t2 extends Phalcon\Mvc\Model
{
    public $id;
    public $name;

    public function initialize()
    {
        $this->setSource('t2');
    }
}

and I do $t1 = t1::findFirst(), I expected $t1->t2_id to contain the object of t2, so I can access the t2 object direclty via $t1->t2_id->id and $t1->t2_id->name.

Is that not how it's supposed to work? I couldn't find that specific case in the documentation so any help is appreciated

Thanks



13.8k

You have to add the relation to both models.

I've already tried it with the relations in both models, didn't work either so I skipped it for the example. I've read some threads were others have similar problems and came across an alias (apparently 4th optional parameter in hasOne()), I will try that later

It should be belongsTo, not hasOne. hasOne is just same realtion as hasMany, just returns one record instead of resultset. hasOne for relation 1 to 1 but when you need to access record which has relation to current record. So in your case for example it should be:

In t1 class:

$this->belongsTo('t2_id', 't2', 'id', ['alias' => 't2');

In t2 class:

$this->hasOne('id', 't1', 't2_id', ['alias' => 't1');

It should be belongsTo, not hasOne. hasOne is just same realtion as hasMany, just returns one record instead of resultset. hasOne for relation 1 to 1 but when you need to access record which has relation to current record. So in your case for example it should be:

In t1 class:

$this->belongsTo('t2_id', 't2', 'id', ['alias' => 't2');

In t2 class:

$this->hasOne('id', 't1', 't2_id', ['alias' => 't1');

hmm, I will try that when I get home, but - from a linguistical point of view - doesn't this seem counterintuitive? For example let's say t1 is Users and t2 is Addresses, a user "has one" address, a user doesn't "belong to" an address (but an address "belongs to" a user)

This says that in class t1 class t2_id column/property belongsTo t2 class. And t2 has one model which relates to it.

This says that in class t1 class t2_id column/property belongsTo t2 class. And t2 has one model which relates to it.

well now it makes perfect sense, what threw me off was the object pointer ($this) itself. I've read it like: "this(t1) hasOne t2" :D

aaaand I'm confused again. It doesn't matter if I use either hasOne() or belongsTo() in t1 and no relationship in t2 at all, and it works. The only thing I had to do is to set an alias, which is not even in the docs (found it on other discussions)