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

Why the models with relationships can't be saved?

Two tables:

CREATE TABLE  `users` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(32) default NULL
  PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `privileges` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(64) NOT NULL,
  `users_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

Models:

class Users Extends Model
{
    //...
    public function initialize()
    {
        $this->hasOne('id', 'Privileges', 'users_id', ['alias' => 'privilege']);
    }
}
class Privileges extends Model
{
    const NAME_ADMINISTRATOR = "Administrator";
    const NAME_ULTRAMAN = "Ultraman";   
    // ...  
    public function initialize()
    {
        $this->belongsTo('users_id', 'Users', 'id');
    }
}

In the UsersController:

public function editAction($id)
{
    $user = Users::findFirstById($id);

    if ($this->request->isPost())
    {
        // After $user->save(), I want to save this user's privileges.

        // this will post 'Administrator' or 'Ultraman'
        $privilege = $this->request->getPost("privilege");

        if (! empty($privilege))
        {

            if (isset($user->privilege->id)) {
                $user_privilege = Privileges::findFirstById($user->privilege->id);
            } else {
                $user_privilege = new Privileges();
                $user_privilege->users_id = $user->id;
            }

            //New Group!!! But it seems can't be modified!
            $user_privilege->name = $privilege; 

            // modify the user's group
            if ($user_privilege->save() == false) {
                foreach ($user_privilege->getMessages() as $message) {
                    $this->flash->error((string) $message);
                }
            } else {
                $this->flash->success($user->name . " User's Group Modified successfully!");
            }

        }

    }
}

The code $user_privilege->save() CAN insert a user's new privilege, but it CANNOT modify a user's privilege! (Can't modify it's privileges.name). Why?

You have any error from getMessages ?



31.3k

I've got a success message as the code give.

You have any error from getMessages ?

edited Dec '15

Well you have all those properties in classes right ? I dont really know whats going on. Maybe just do findFirst instead of findFirsyById ?



31.3k

Oh~ sorry, the code above is not complete. The editAction is exactly like this:

public function editAction($id)
{
    $user = Users::findFirstById($id);

    if ($this->request->isPost())
    {
        // After $user->save(), I want to save this user's privileges.

        // this will post 'Administrator' or 'Ultraman'
        $privilege = $this->request->getPost("privilege");

        if (! empty($privilege))
        {
            if (isset($user->privilege->id)) {
                $user_privilege = Privileges::findFirstById($user->privilege->id);
            } else {
                $user_privilege = new Privileges();
                $user_privilege->users_id = $user->id;
            }

            //New Group!!! But it seems can't be modified!
            $user_privilege->name = $privilege; 

            // modify the user's group
            if ($user_privilege->save() == false) {
                foreach ($user_privilege->getMessages() as $message) {
                    $this->flash->error((string) $message);
                }
            } else {
                $this->flash->success($user->name . " User's Group Modified successfully!");
            }

            // Here I also save the user data
            if ($user->save() == false) {
                foreach ($user->getMessages() as $message) {
                    $this->flash->error((string) $message);
                }
            } else {
                $this->flash->success("updated!");
            }
        }
    }
}

After the $user_privilege->save(), I also save the user's data by $user->save(), then the user's privilege is updated twice! And finnaly it changed to the original value!

It seems that $user_privilege->save() is not necessary, But I don't know how to code the $user->save() that the user's privilege name value will change automaticly when call $user->save().

Well you have all those properties in classes right ? I dont really know whats going on. Maybe just do findFirst instead of findFirsyById ?

Well - thats why you have relation - try

$user->privilege = $user_privilege

And then when you will do $user->save() it should save both $user and $user_privilege.



31.3k

It's odd~~~ I delete the $user_privilege->save() and remain the $user->save(), the user's privilege can't be modified!

Then I try to do the follow things by order:

  1. execute $user_privilege->save()
  2. $user->privilege = $user_privilege
  3. $user->save()

It still remains the original value!

The first step changes the value, and $user->privilege = $user_privilege is obviously executed, but the third step changes the value to original value.

Did the $user->privilege = $user_privilege can't change the real value of object $user? Or is it because of privilege is a alias name?

Well - thats why you have relation - try

$user->privilege = $user_privilege

And then when you will do $user->save() it should save both $user and $user_privilege.

What will happen if you do $user_privileage = $user->privilege; Instead of finding this privileage ?



31.3k

I think it works properyly. Instead of $user_privilege = Privileges::findFirstById($user->privilege->id);, I just select a user by $user = Users::findFirstById($id);, and then print it out.

$user_privilege = $user->privilege;
$this->view->up = $user_privilege;

var_dump($up) in the viewer, the result is:

object(YZOI\Models\Privileges)[97]
  public 'id' => string '4' (length=1)
  public 'name' => string 'Administrator' (length=13)
  public 'active' => string 'Y' (length=1)
  public 'users_id' => string '3' (length=1)
  protected '_dependencyInjector' => 
    object(Phalcon\Di\FactoryDefault)[7]
      protected '_services' => 
        array (size=25)
          'router' => ...

What will happen if you do $user_privileage = $user->privilege; Instead of finding this privileage ?

But what you mean ? If you do $user->privilege you will select privilge by alias name. There will be no $user->privilege until you dont use it.



31.3k
edited Dec '15

By alias name, I can select the privilege, but can't modify the database value ! is it?

But what you mean ? If you do $user->privilege you will select privilge by alias name. There will be no $user->privilege until you dont use it.