1
votes

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

1
In your code "payers" is a defined relation, NOT a attribute or database row. If a model is pupulated with values correctly, you can simpy call $model->save(). It is well documented ActiveRecordR13e

1 Answers

2
votes

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.