voskobovich / yii2-linker-behavior

This behavior makes it easy to maintain many-to-many and one-to-many relations in your ActiveRecord models in Yii2.
Other
80 stars 19 forks source link

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

Open gvlasov opened 7 years ago

gvlasov commented 7 years ago

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); // []
voskobovich commented 6 years ago

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(),
                        ]) ?>
gvlasov commented 6 years ago

@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() { ... }]
  )
?>
Sensetivity commented 6 years ago

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.

voskobovich commented 6 years ago

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.