yii2-linker-behavior icon indicating copy to clipboard operation
yii2-linker-behavior copied to clipboard

Attribute with the many-to-many relation doesn't have a value of type array when linking 0 records

Open gvlasov opened this issue 7 years ago • 4 comments

There is an issue that happens when you want to link a model to 0 records.

HTML doesn't seem to provide any way to send an empty array in form data. So in order to save 0 values in a MtM relation using this behavior, you'd have to use a special value that represents an empty array. This can be done with unselect attribute when creating a list of inputs.

So when data is passed from controller to this behavior during $model->load(), if you selected 0 elements in the form inputs that represent our many-to-many relation, then in the attribute you'll have that special value (empty string '' by default) instead of an array. So in your attribute for the many-to-many relation, you'll have that value instead of an array. This may have a number of obvious consequences. For me it complicates validation, as you have to keep in mind (and in documentation for your project) that there may be a special value instead of empty array.

What I suggest:

  1. Have a configuration parameter for the behavior to choose the value that represents an empty array, '' by default
  2. Automatically translate that value into an array when accessing the many-to-many relationship attribute after loading form data into the model, so instead of this:
var_export($house->dweller_ids); // ''

you'd get this:

var_export($house->dweller_ids); // []

gvlasov avatar Aug 21 '17 14:08 gvlasov

Please, show the code by which you create the <select> element.

This is my code from real project

                    <?= $form->field($model, 'artist_ids')
                        ->widget(Select2Widget::class, [
                            'options' => [
                                'multiple' => true,
                                'class' => 'form-control',
                            ],
                            'bootstrap' => true,
                            'items' => Artist::listAll(),
                        ]) ?>

voskobovich avatar Dec 01 '17 13:12 voskobovich

@voskobovich I don't use a select element. I create checkboxes. I can't show you the code, but basically it is like this:

<?=
$form->field($model, 'some_ids')
  ->checkboxList(
    $children,
    ['item' => function() { ... }]
  )
?>

gvlasov avatar Dec 01 '17 20:12 gvlasov

Checkbox by default should check 2 elements. One of it was hidden and have a default value 0. So it can save relation with false checked checkbox. Empty string what you get it some problem with your HTML or form. By default for checkbox value is 0 or 1.

Sensetivity avatar May 18 '18 12:05 Sensetivity

I can not tell you how to solve your problem. You must build an HTML element so that an array with IDs is sent to the backend. I'm sure there are many ways to do this.

voskobovich avatar May 27 '18 15:05 voskobovich