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.

Cannot save a record using its relationship

Hello,

Given the following two very basic models:

class User extends \Phalcon\Mvc\Model {
    public $id;
    public $password;

    public function initialize() {
        $this->hasOne('id', 'Person', 'user_id', [
            'alias' => 'corresponding_person'
        ]);
    }
}
// CREATE TABLE User (
//   id int(10) NOT NULL AUTO_INCREMENT,
//   password VARCHAR(30),
//   PRIMARY KEY (id)
// );
class Person extends \Phalcon\Mvc\Model {
    public $id;
    public $user_id;
    public $name;

    public function initialize() {
        $this->hasOne('user_id', 'User', 'id', [
            'alias' => 'corresponding_user'
        ]);
    }
}
// CREATE TABLE Person (
//   id int(10) NOT NULL AUTO_INCREMENT,       
//   user_id int(10) NOT NULL,
//   name VARCHAR(30),
//   PRIMARY KEY (id)
// );

and this controller:

class IndexController extends ControllerBase {

    public function indexAction() {
        $User = new User();
        $User->password = 'secret';
        $User->save();

        $Person = new Person();
        $Person->name = 'John';
        $Person->corresponding_user = $User;

        if (! $Person->save()) {
            die(
                'Messages : ' . print_r($Person->getMessages(), true) . "\n" . 
                '$User->id : ' . $User->id
            );
        }
    }
}

When I run the controller, I get:

Messages : Array
(
    [0] => Phalcon\Mvc\Model\Message Object
        (
            [_type:protected] => PresenceOf
            [_message:protected] => user_id is required
            [_field:protected] => user_id
            [_model:protected] => 
            [_code:protected] => 0
        )
)
$User->id : 4

$User is saved, but not $Person.

It works if I use $Person->user_id = $User->id; but shouldn' it also work using the relationship defined in the model?

(Note: removing the relationship aliases and using $Person->User = $User produces the same error)

Thanks in advance for any help



5.0k
Accepted
answer
edited Jun '14

By chance I am currently also dealing with hasOne relationships (or 1:0..1 relationships to be more precise). Also having trouble getting stuff saved when specifiying the related model/record..

What happens if you change the hasOne in Person to belongsTo?



4.7k

Thank you renskii, it works. But then I'm confused: if I have to use belongsTo for 1-1 relationships, when am I supposed to use hasOne??? :-|



5.0k
edited Jun '14

@kofkof01 yes, I am also confused.. :) I was already planning on opening a topic on this, but it seems you kinda beat me to the punch ;)

The docs seem to explain belongsTo differently. Here: http://docs.phalconphp.com/en/latest/reference/models.html#defining-relationships it sais: Defines a n-1 relationship

In the API reference http://docs.phalconphp.com/en/latest/api/Phalcon\%5Mvc\%5Model.html there is: Setup a relation reverse 1-1 between two models

There's little info to be found on hasOne. So I am not really sure.. :)

edit: btw - if your relationship is 1:1, you can remove id from Person of course, and just use user_id as your PK (?) So I guess you can 'denote' 1 table as the 'master table' (having an auto-increment id), and add the belongsTo to the related 1:1?



13.2k
edited Jun '14

I usually think like that:

A Person has User

A User belongs to Person



4.7k
edited Jun '14

@sn0opr, I think it's the other way round. I've just found this in CakePHP doc:

The belongsTo association is a natural complement to the hasOne and hasMany associations: it allows us to see the data from the other direction.

[...]

If a model(table) contains a foreign key, it belongsTo the other model(table).

So if Phalcon works the same (and I bet it does), it seems a 1-1 relationship must be declared by using:

  • belongsTo() in the referencing model (the one with the foreign key)
  • hasOne() in the referenced model (the one the foreign key points to)

...which would explain why @renskii's solution works.



5.0k

@kofkof01 nice find. Seems plausible!