We are moving our forum in GitHub Discussions. For questions about Phalcon v3/v4 you can visit here and for Phalcon v5 here.

Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

hasOne not working

I have these 2 tables:

CREATE TABLE IF NOT EXISTS `persons` (
    `person_id` int(11) NOT NULL AUTO_INCREMENT,
    `str_name` varchar(50) NOT NULL,
    `str_last_name` varchar(50) NOT NULL,
    `dt_birthday` date NOT NULL,
    `country_id` int(11) DEFAULT NULL,
    PRIMARY KEY (`person_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
CREATE TABLE IF NOT EXISTS `users` (
    `user_id` int(11) NOT NULL AUTO_INCREMENT,
    `str_usr` varchar(35) NOT NULL,
    `str_email` varchar(50) NOT NULL,
    `str_pwd` varchar(40) NOT NULL,
    `person_id` int(11) NOT NULL,
    PRIMARY KEY (`user_id`),
    UNIQUE KEY `indx_person_id` (`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
ALTER TABLE `users`
    ADD CONSTRAINT `users_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `persons` (`person_id`) ON DELETE CASCADE ON UPDATE NO ACTION;

Now, I have these 2 models:

class Person extends \Phalcon\Mvc\Model {

    public function getSource() {
        return "persons";
    }

    public function initialize() {

    }

    public function columnMap() {
        return array(
            'person_id' => 'id',
            'str_name' => 'name',
            'str_last_name' => 'lastName',
            'dt_birthday' => 'dBirhtday',
            'country_id' => 'country'
        );
    }
}

And

class User extends \Phalcon\Mvc\Model {

    public function getSource() {
        return "users";
    }

    public function initialize() {
        $this->hasOne("person", "Person", "id");
    }

    /**
     * Mapeamento das colunas do db para aplicação
     * @return array
     */
    public function columnMap() {
        return array(
            'user_id' => 'id',
            'str_usr' => 'usrName',
            'str_email' => 'email',
            'str_pwd' => 'password',
            'person_id' => 'person'
        );
    }

    public $person; //field to load the person
}

I omitted the getters/setters and fields due the space.

When I try to load the person from a user it is null. Why???



43.8k
edited Jul '14

You have to declare the relations in the Users model class:

public function initialize()
{
    $this->hasOne("id", "Person", "person");
}


4.0k
edited Jul '14

Ok, I did it as you suggest but when I load the user object, the person attribute holds the value of the person primary key. If I print

var_dump($user->getPerson());

It is not printing the person object instead it is printing the person pk.



98.8k

It must be:

public function initialize()
{
    $this->hasOne("person_id", "Person", "person_id");
}

http://docs.phalcon.io/en/latest/reference/models.html#defining-relationships



4.0k
Accepted
answer
edited Jul '14

I got it working this way...

public function initialize() 
{
    $this->belongsTo("person", "Person", "id", [
        'alias' => 'pessoa'
    ]);
}

But I have to use alias instead of getPerson attribute. The attribute just return the persons id.

Hi,

I've got a similar problem and thanks to this topic I partially answered my question! So, my other problem is about conditions on foreign table. To adapt my problem to the example of OpsRJ, basically I would like to do that :

User::find(array(
    'conditions' => 'pessoa.name = :name:',
    'bind' => array('name' => 'John')
));

Unfortunately I got this :

Unknown model or alias 'pessoa' (1), when preparing: SELECT [Phoenix\Models\User].* FROM [Phoenix\Models\User] WHERE pessoa.name = :name:

More informations

My two models are in different namespaces. For example, Phoenix\Core\Models\Person and Phoenix\Models\User so I declare my contrains with the correct namespace. Something like that :

$this->hasOne('id', 'Phoenix\Models\User', 'person');

$this->belongsTo('person', 'Phoenix\Core\Models\Person', 'id', [
    'alias' => 'pessoa'
]);

Thanks for your help!