Saving “many-to-many” in Yii2 through behavior

CleanTalk is a SaaS spam protection service for Web-sites. CleanTalk uses protection methods which are invisible for site visitors. Connecting to the service eliminates needs for CAPTCHA, questions and answers and other methods of protection, complicating the exchange of information on the site.

bbc47933552e4c90846c80e731b06ddfIf you had to work with Yii2 sure there was a situation when it was necessary to keep communication “many-to-many”.

When it became clear that the network has no behaviors to work with this type of connection, then the correct code was written at the event «after save» and with a warning “works well also” went to the repository.

Personally, I am not satisfied with such a disposition of events. I decided to write something very magical behavior, which is so lacking in the official assembly Yii2.

Installation

Install through the Composer:

php composer.phar require --prefer-dist voskobovich/yii2-many-many-behavior "*"

Or add into composer.json of your project to the section «require»:

"voskobovich/yii2-many-many-behavior": "*"

Execute:

~$ php composer.phar update

Source: yii2-many-many-behavior.

How to use?

Connecting the behavior in the desired model ActiveRecord:

public function behaviors()
{
    return [
        [
            'class' => \voskobovich\behaviors\ManyToManyBehavior::className(),
            'users_list' => 'users',
            'tasks_list' => [
                'tasks',
                'get' => function($value) {
                    return JSON::decode($value);
                },
                'set' => function($value) {
                    return JSON::encode($value);
                },
             ]
        ],
    ];
}

This example describes two connections:

  1. Communication «users» will receive and store the primary keys in the properties of the model «users_list».
  2. Communication «tasks» respectively «tasks_list». At the same time, for a given connection are indicated handlers «set» and «get» which process data before saving the communication and output in the field.

Please note that the properties of «users_list» and «tasks_list» will appear in the model automatically!

Next, add fields in the form of creating/edit:

<?= $form->field($model, 'users_list')
      ->dropDownList(ArrayHelper::map(User::find()->all(), 's_id', 'name'), ['multiple' => true]) ?>

and allow them to update through mass assignment by adding validation rules:

public function rules()
{
    return [
        [['users_list', 'tasks_list'], 'safe']
    ];
}

or you can work with new properties directly:

$model->users_list = [2,5,6,7];

After these manipulations links will be updated automatically.

From the properties of «users_list» and «tasks_list» you can also get an array of primary keys stored on communication models.

print_r($model->users_list);

Returns an array of primary keys stored on the communication «users».

It is worth saying that the formation of a list of primary keys happens only at the moment of the call of reading properties.

Thank you for your attention!

This text is a translation of the article “Сохранение “много ко многим” в Yii2 через поведение” by rafic published on habrahabr.ru.

Forums and blogs without spam

CleanTalk is a SaaS spam protection service for Web-sites. CleanTalk uses protection methods which are invisible for site visitors. Connecting to the service eliminates needs for CAPTCHA, questions and answers and other methods of protection, complicating the exchange of information on the site.

Leave a Reply

Your email address will not be published. Required fields are marked *