Nimer
Nimer

Reputation: 355

Yii2 saving model with relationship property

iam trying to save model from form, that have relationship defined via junction table, but since the property is relationship object it is read-only and it fails on validation.

Model relationship:

public $payer
/**
 * @return \yii\db\ActiveQuery
 */
public function getPayerRelationship()
{
    return $this->hasMany(PartyRelationship::className(), ['contract_id' => 'id'])->where(['relationship' => 'P']);
}

public function getPayers(){
    return $this->hasMany(ContractingParty::className(), ['id' => 'contracting_party_id'])
        ->via('payerRelationship');
}
public function getContractors() {  // could be a static func as well
    $model = ContractingParty::find()->asArray()->all();
    return ArrayHelper::map($model, 'id', 'subject_name');
}

Form view:

<?= $form->field($model, 'payers')->widget(Select2::classname(), [
    'data' => $model->getContractors(),
    'language' => 'en',
    'options' => ['placeholder' => '-- Select company --'],
    'pluginOptions' => [
        'allowClear' => true,
        'multiple' => true,
    ],
    'showToggleAll' => false

]) ?>

It wont validate or save, because of read-only property payers. I tried to use different property in $form->field($model, 'payer'... (instead of payers), then validation works and even saving works, but trouble is, that editing have no preselected values of that model, because they are in model->payers. And i have no idea, what iam supposed to pass here instead of this relationship object (or property of model in general).

Maybe iam plainly blind, but in manual there is a lot of information about getting data from db, but almost no info about saving. (btw. i saw this post: Yii2 Invalid Call: Setting read-only property - but that didnt give me any new piece of information at all).

Is my form design wrong, or model design (Meaning i should just create form field using two models)? Thanks

Upvotes: 1

Views: 3067

Answers (1)

Adam Vt&#237;pil
Adam Vt&#237;pil

Reputation: 90

Adding setters to model:

public function setPayer(){
    $payer_id_array = array();
    $payer_array = ArrayHelper::toArray($this->payers);
    foreach ($payer_array as $value){
        $payer_id_array [] = $value['id'];
    }
    $this->payer = $payer_id_array;
}

public function setRecipient(){
    $recipient_id_array = array();
    $recipient_array = ArrayHelper::toArray($this->recipients);
    foreach ($recipient_array as $value){
        $recipient_id_array [] = $value['id'];
    }
    $this->recipient = $recipient_id_array;
}

and manually into controller (action create and update):

$model->setPayer();
$model->setRecipient();

seems to fix the conflict between the names of relation and property passed into the field.

Upvotes: 2

Related Questions