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

cant save relation model

hi everyone! sorry for my bad english. begin..

$phql = "SELECT acl_role.*, user.*
    FROM Myproj\Frontend\Models\Acl_role AS acl_role
    JOIN Myproj\Frontend\Models\User AS user 
    ON
    acl_role.id = user.acl_role_id
    WHERE
    user.email = '$email'    
    AND
    user.password = '$pass'";

$res = $this->modelsManager->executeQuery($phql);
if($res->valid()){
 $row = $res[0];
 $row->user->acl_role = $row->acl_role;
 $user = $row->user;
}

now in $user User model with relation model Role

Role 1-to-many User

I need change role to another

$role = Myproj\Frontend\Models\Acl_role::findFirst(Myproj\\Frontend\Models\Acl_role::ADMIN);

echo $user->acl_role_id; //1

$user->acl_role = $role // User: $this->belongsTo('acl_role_id', __NAMESPACE__.'\Acl_role', 'id',['alias' => 'acl_role']);
$user->acl_role_id = Myproj\\Frontend\Models\Acl_role::ADMIN; 

echo $user->acl_role_id; //3 - so good

$user->save(); // return true, it s good too

echo $user->acl_role_id; //1 Shit!!!! Not good! 

How I can save it ?



2.6k
edited Jun '14

I think $role might not be the Object you think it is. What value does $role->getId() have?

If the belongsTo is correct then $user->acl_role = $role; should be enough. No need to set the id yourself.

What I think is going on.

  1. $role = Acl_role::findFirst(Acl_role::ADMIN);
    $role is not the intended object with id 3, but instead is an object with id 1.

  2. $user->acl_role = $role; Assigns the $role with id 1.
    $user->acl_role_id is not yet set

  3. $user->acl_role_id = Acl_role::ADMIN; Manually sets acl_role_id, Thus echo return 3.

  4. $user->save(); Runs the belongsTo magic, setting the acl_role_id using the incorrect $role.

If the following returns 1 the wrong $role is found.

$user->acl_role = Acl_role::findFirst(Acl_role::ADMIN);
$user->save();
echo $user->acl_role_id;
edited Oct '14

I think I found where not working

$user = $auth->identify($email,$password);
    d($user); // d() - var_dumping function
    $role = Acl_role::findFirst(Acl_role::ADMIN);
    $user->acl_role = $role;
    d($user);
    $role = Acl_role::findFirst(Acl_role::GUEST);
    $user->acl_role = $role;
    d($user);

No, that's all right. When I send a Select query , it returns the object $user, which has no relation (why?) the model Role. Array protected '_related' = null in User object. Maybe here some LazyLoading, but loading Role has already happened with Join and re-query the Database should not occur when accessing a Role, I think ? Or am I wrong?

I then set the Admin role, everything is OK here. (second dumping):

protected '_related' => 
array (size=1)
  'acl_role' => 
    object(Oknovik\Frontend\Models\Acl_role)[85]
      public 'id' => string '3' (length=1)
      public 'name' => string 'Admin' (length=5)
      protected '_dependencyInjector' => 
        object(Phalcon\DI\FactoryDefault)[1]      

......

  public 'acl_role' => 
  object(Oknovik\Frontend\Models\Acl_role)[85]
    public 'id' => string '3' (length=1)
    public 'name' => string 'Admin' (length=5)
    protected '_dependencyInjector' => 
      object(Phalcon\DI\FactoryDefault)[1]
        public '_services' => 
          array (size=30)

              ...

But then again I install a Guest Role, but in the array protected '_related' preserved object Admin Role, at a time when public acl_role object Guest

protected '_related' => 
array (size=1)
  'acl_role' => 
object(Oknovik\Frontend\Models\Acl_role)[85]
  public 'id' => string '3' (length=1)
  public 'name' => string 'Admin' (length=5)
  protected '_dependencyInjector' => 
    object(Phalcon\DI\FactoryDefault)[1]

.........

          public 'acl_role' => 
      object(Oknovik\Frontend\Models\Acl_role)[89]
        public 'id' => string '1' (length=1)
        public 'name' => string 'Guest' (length=5)
        protected '_dependencyInjector' => 
          object(Phalcon\DI\FactoryDefault)[1]
            public '_services' => 
              array (size=30)

When I re-set the Role to a User without saving intermediate values, remains Role installed the first but not the last.
In my opinion this is strange behavior.