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???



30.7k
edited Jul '14

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

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


2.6k
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.



84.5k

It must be:

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

http://docs.phalconphp.com/en/latest/reference/models.html#defining-relationships



2.6k
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!