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

Saving multiple Child related records on the same model.

I am trying to save multiple related child records on a single transaction.

I am sending over the data as an array on the users form

Parent Model: Users

public $id;
.....
public function initialize()
{
$this->hasMany('id', 'UsersCompliance','userId',array(
    'alias' => 'usersCompliance',
    'foreignKey' => array(
        'action' => Relation::ACTION_CASCADE
)));
}

Child Model: Compliance

public $id;
public $userId;
public $key;
public $value;
public function initialize()
{
    $this->belongsTo('userId','Users','id');
}

I would like a way to dynamically create new key=>value pairs and/or update existing key value pairs multiple at a time. Was able to get a single to update a time using this logic here.

foreach($this->request->getPost('compliance') as $key => $value){
  $comp = new UsersCompliance();
  $comp->userId = $user->id;
  $comp->name = $key;
  $comp->value = $value;

  $user->usersCompliance = $comp;
  }
}

Now obviosuly i have already set a usersComplaince, but by definition of the model this should accept multiple no? This also has the undesired affect of simply creating a new line item instead of updating an existing one if it already exists.

I can add in some logic to test in every iteration and solve the issue of duplication. but i can't get it to save more than one record at a time. soemthing like the following woudl be nice.

    // if doesn't match an existing add to the new save result set etc. 
  $user->usersCompliance[] = $comp;

This syntax does not trigger __set in the model which is used to set related models.

$user->usersCompliance[] = $comp;

Getting this from phalcon. Phalcon\Mvc\Model\Exception: Cursor is an immutable ArrayAccess object



125.8k
Accepted
answer

In your loop, throw your $comp objects into an array. After the loop, set usersCompliance to that array, then save $user

$comps = [];
foreach($this->request->getPost('compliance') as $key => $value){
  $comp = new UsersCompliance();
  $comp->userId = $user->id;
  $comp->name = $key;
  $comp->value = $value;

  $comps[] = $comp;
}

$user->usersCompliance = $comps;
$user->save();

Thank you Quasipickle, for some reason it doesn't like the array set directly to the object.

Well like Andres said - it doesn't trigger __set().

Dylan Aanderson, In edit view, this way is duplicating the n-m relationship