Giter Site home page Giter Site logo

yii2-linker-behavior's Introduction

Yii2 Linker Behavior

This is a NEW version of a Yii2 ManyToMany Behavior.
It's the Yii2 ManyToMany Behavior only in new implementation architecture.


Что это?

Это копия Yii2 ManyToMany Behavior но с другой архитектурой.

В Yii2 ManyToMany Behavior некоторые жаловались, что у сохранения много-ко-многим одна логика и она не всем подходит.
Я сделал так, что логику обновления связей можно конфигурировать без перепилки кода.

В этой сборке реализовано три класса логики (апдейтера):

  • ManyToManyUpdater.php - удаляет все связи и перезаписывает их заново. Его преимущество в том, что обновление происходит за 2 запроса в БД. Подходит для небольшого количества обновляемых связей за раз.
  • ManyToManySmartUpdater.php - находит разницу и вносит корректировки в связи (удаляет старые, добавляет новые). Он производит уже за 4 запроса, но при этом не убивает существующие связи.
  • OneToManyUpdater.php - логика работы со связью один-ко-многим. Просто берем Primary Key и присваиваем его к дочерним элементам.

Все это позволяет разработчикам писать свою логику обновления связей с блекджеком и девочками для своих проектов.
В репо есть интерфейсы, абстрактные классы и все, что нужно для расширения.

Сейчас проект в стадии RC и на новый функционал нужно допилить тестов.
Но в целом тесты которые были на Yii2 ManyToMany Behavior на этой архитектуре проходят успешно.
Так что уже можно юзать.

Что на счет совместимости с Yii2 ManyToMany Behavior?

Изменились только параметры конфигурирования компонента.
Нужно просто внимательно свериться с докой README.md и все будет хорошо.


This behavior makes it easy to maintain many-to-many and one-to-many relations in your ActiveRecord models.

License Latest Stable Version Latest Unstable Version Total Downloads Build Status

Support

GutHub issues.

Usage

  1. In your model, add the behavior and configure it
  2. In your model, add validation rules for the attributes created by the behavior
  3. In your view, create form fields for the attributes

Adding and configuring the behavior

As an example, let's assume you are dealing with entities like Book, Author and Review. The Book model has the following relationships:

public function getAuthors()
{
    return $this->hasMany(
        Author::className(),
        ['id' => 'author_id']
    )->viaTable(
        '{{%book_has_author}}',
        ['book_id' => 'id']
    );
}

public function getReviews()
{
    return $this->hasMany(Review::className(), ['id' => 'review_id']);
}

In the same model, the behaviour can be configured like so:

public function behaviors()
{
    return [
        [
            'class' => \voskobovich\linker\LinkerBehavior::className(),
            'relations' => [
                'author_ids' => 'authors',
		'review_ids' => 'reviews',
            ],
        ],
    ];
}

Relation names don't need to end in _ids, and you can use any name for a relation. It is recommended to use meaningful names, though.

Adding validation rules

The attributes are created automatically. However, you must supply a validation rule for them (usually a safe validator):

public function rules()
{
    return [
        [['author_ids', 'review_ids'], 'each', 'rule' => ['integer']]
    ];
}

Creating form fields

By default, the behavior will accept data from a multiselect field:

<?= $form->field($model, 'author_ids')
    ->dropDownList($authorsAsArray, ['multiple' => true]) ?>
...
<?= $form->field($model, 'review_ids')
    ->dropDownList($reviewsAsArray, ['multiple' => true]) ?>

Known issues and limitations

  • Composite primary keys are not supported.
  • Junction table for many-to-many links is updated using the connection from the primary model.
  • When using a function to calculate the default value, keep in mind that this function is called once, right before the relations are saved, and then its result is used to update all relevant rows using one query.
  • Relations are saved using DAO (i. e. by manipulating the tables directly).

Custom getters and setters

Attributes like author_ids and review_ids in the Book model are created automatically. By default, they are configured to accept data from a standard select input (see below). However, it is possible to use custom getter and setter functions, which may be useful for interaction with more complex frontend scripts. It is possible to define many alternative getters and setters for a given attribute:

//...
'author_ids' => [
    'authors',
    'fields' => [
        'json' => [
            'get' => function($value) {
                //from internal representation (array) to user type
                return JSON::encode($value);
            },
            'set' => function($value) {
                //from user type to internal representation (array)
                return JSON::decode($value);
            },
        ],
        'string' => [
            'get' => function($value) {
                //from internal representation (array) to user type
                return implode(',', $value);
            },
            'set' => function($value) {
                //from user type to internal representation (array)
                return explode(',', $value);
            },
        ],
    ],
]
//...

Field name is concatenated to the attribute name with an underscore. In this example, accessing $model->author_ids will result in an array of IDs, $model->author_ids_json will return a JSON string and $model->author_ids_string will return a comma-separated string of IDs. Setters work similarly.

Getters and setters may be ommitted to fall back to default behavior (arrays of IDs).

NOTE

The setter function receives whatever data comes through the $_REQUEST and is expected to return the array of the related model IDs. The getter function receives the array of the related model IDs.

COMPATIBILITY NOTE

Specifying getters and setters for the primary attribute (author_ids in the above example) is still supported, but not recommended. Best practice is to use primary attribute to get and set values as array of IDs and create fields to use other getters and setters.

Custom junction table values

For setting additional values in junction table (apart columns required for relation), you can use viaTableAttributesValue:

...
'author_ids' => [
    'authors',
    'updater' => [
        'viaTableAttributesValue' => [
            'status_key' => BookHasAuthor::STATUS_ACTIVE,
            'created_at' => function() {
                return new \yii\db\Expression('NOW()');
            },
            'is_main' => function($updater, $relatedPk, $rowCondition) {
                /**
                 * $updater this is a object of current updater that implement UpdaterInterface.
                 * $relatedPk this is a Primary Key of related object.
                 * $rowCondition this is a object of current row state, that implement AssociativeRowCondition.
                 */
                 
                /**
                 * How i can get the Primary Model?
                 */
                $primaryModel = $updater->getBehavior()->owner;
                
                /**
                 * How i can get the Primary Key of Primery Model?
                 */
                $primaryModelPkValue = $primaryModel->getPrimaryKey();
                 
                return array_search($relatedPk, $primaryModel->author_ids) === 0;
            },
        ],
    ]
]
...

Setting default values for orphaned models

When one-to-many relations are saved, old links are removed and new links are created. To remove an old link, the corresponding foreign-key column is set to a certain value. It is NULL by default, but can be configured differently. Note that your database must support your chosen default value, so if you are using NULL as a default value, the field must be nullable.

You can supply a constant value like so:

...
'review_ids' => [
    'reviews',
    'updater' => [
        'fallbackValue' => 17,
    ]
],
...

It is also possible to assign the default value to NULL explicitly, like so: 'fallbackValue' => null. Another option is to provide a function to calculate the default value:

...
'review_ids' => [
    'reviews',
    'updater' => [
        'fallbackValue' => function($model, $relationName, $attributeName) {
            //default value calculation
            //...
            return $fallbackValue;
        },
    ]
],
...

The function accepts 3 parameters. In our example $model is the instance of the Book class (owner of the behavior), $relationName is 'reviews' and $attributeName is 'review_ids'.

If you need the db connection inside this function, it is recommended to obtain it from either the primary model (Book) or the secondary model (Review).

function($model, $relationName, $attributeName) {
    //get db connection from primary model (Book)
    $connection = $model::getDb();
    ...
    //OR get db connection from secondary model (Review)
    $secondaryModelClass = $model->getRelation($relationName)->modelClass;
    $connection = $secondaryModelClass::getDb();
    ...
    //further value calculation logic (db query)

Applying the behaviour several times to a single relationship

It is possible to use this behavior for a single relationship multiple times in a single model. This is not recommended, however.

Using the behaviour with relations that are using the same junction table

When you are implementing multiple ManyToMany relations in the same model, and they are using same junction table, you may face and issue when your junction records will not be saved properly.

This happens because old junction records are dropped each time new relation is saved. To avoid deletion of records that were just saved, you will need to set viaTableCondition param.

This delete condition will be merged with primary delete condition and may be used to fine tune your delete query.

For example, let's imagine that we develop a scientific database for botanical laboratory. We have a model called "Sample" for different plants samples, model called "Attachment" for related files (photos or documents) and junction table "sample_attachments". And we want to divide all those files into separate fields in the "Sample" model (raw material pictures, molecular structure, etc) by introducing field "type" in the junction table. In such case, the resulting "Sample" model will look like this:

    public function behaviors()
    {
        return [
            'manyToMany' => [
                'class' => LinkerBehavior::className(),
                'relations' => [
                    'rawMaterialPicturesList' => [
                        'rawMaterialPictures',
                        'updater' => [
                            'viaTableAttributesValue' => [
                                'type_key' => 'RAW_MATERIAL_PICTURES',
                            ],
                            'viaTableCondition' => [
                                'type_key' => 'RAW_MATERIAL_PICTURES',
                            ],
                        ]
                    ],
                    'molecularStructureList' => [
                        'molecularStructure',
                        'updater' => [
                            'viaTableAttributesValue' => [
                                'type_key' => 'MOLECULAR_STRUCTURE',
                            ],
                            'viaTableCondition' => [
                                'type_key' => 'MOLECULAR_STRUCTURE',
                            ],
                        ]
                    ],
                ],
            ],
        ];
    }
    
    public function getRawMaterialPictures()
    {
        return $this->hasMany(
            Attachment::className(),
            ['id' => 'related_id']
        )->viaTable(
            'sample_attachments',
            ['current_id' => 'id'],
            function ($query) {
                $query->andWhere([
                    'type_key' => 'RAW_MATERIAL_PICTURES',
                ]);
                return $query;
            }
        );
    }
    
    public function getMolecularStructure()
    {
        return $this->hasMany(
            Attachment::className(),
            ['id' => 'related_id']
        )->viaTable(
            'sample_attachments',
            ['current_id' => 'id'],
            function ($query) {
                $query->andWhere([
                    'type_key' => 'MOLECULAR_STRUCTURE',
                ]);
                return $query;
            }
        );
    }
    

Installation

The preferred way to install this extension is through composer.

Either run

php composer.phar require --prefer-dist voskobovich/yii2-linker-behavior "^4.0"

or add

"voskobovich/yii2-linker-behavior": "^4.0"

to the require section of your composer.json file.

CODE ECOLOGY

To check the code:

./vendor/bin/phpcs -s --encoding=utf-8 --extensions=php .

To auto fix the code format:

./vendor/bin/php-cs-fixer fix

yii2-linker-behavior's People

Contributors

beowulfenator avatar daveferger avatar githubjeka avatar glagola avatar kfreiman avatar kop avatar sergiobelya avatar vitorarantes avatar voskobovich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yii2-linker-behavior's Issues

Некорректное создание AssociativeRowCondition в ManyToManySmartUpdater

https://github.com/voskobovich/yii2-linker-behavior/blob/4.0.2-rc/src/updaters/ManyToManySmartUpdater.php#L117
На выходе всегда AssociativeRowCondition с isNewRecord = true и пустым значением.
Надо либо передать все в первом параметре, либо сделать что-то с конструктором(т.к. сейчас идет в него, но там ключи - позиции в конструкторе). Например:

$rowCondition = Yii::createObject([
    'class' => $this->rowConditionClass,
    'isNewRecord' => false,
    'oldValue' => $currentRow[$viaTableColumnName],
]);

ПС: Сделать реквест сейчас нет возможности.

Working only Yii >2.0.13( BaseObject)

Hi) I have installed the latest version 4.1.0 in a project with yii 2.0.11.
I get a standard error for yii \ base \ Object)
Maybe you update the YII2 dependency in composer.
Because now, it is indicated incorrectly
"yiisoft / yii2": "^ 2"
with version lower than 2.0.13. will not work.

Тэги к моделям. Как?

Немного поработал с компонентом, но не смог реализовать логику обычных тэгов, т.е. не только запись связей в промежуточную таблицу, но и запись самих тэгов в БД.

Имею три стандартных таблицы post, post_tag, tag. И две модели Post, Tag.
Связи записываются и читаются, дополнительные данные (типа created_at) тоже могут быть записаны в промежуточную таблицу, но вот записать тэг из модели Post не смог.

Какая должна быть логика работы?

Illegal string offset 'updater' LinkerBehavior:122

Доброго времени суток. Столкнулся с такой ошибкой Illegal string offset 'updater' при сохранении модели со следующим поведением:

public function behaviors()
{
    return [
        [
            'class' => \voskobovich\linker\LinkerBehavior::className(),
            'relations' => [
                'authors_ids' => 'authors',
            ],
        ],
    ];
}

Проблема оказалось в том, что при переборе связей, считалось, что $params будет массивом, а я передал строку. Поэтому сделал так:

foreach ($this->relations as $attributeName => $params) {
    //...
    
    // LinkerBehavior:118
    // Make array if it is string
    if(!is_array($params) && is_string($params)) {
        $params = [$params];
    }
    //...
}

Решение не тестировалось при всех случаях, но в моем помогло.

oldAttributes before save

Как я могу посмотреть, что было до обновления сущности в performer_ids? Что-то типо $this->oldAttributes['performer_ids'];

[ 'class' => LinkerBehavior::className(), 'relations' => [ 'performer_ids' => 'performers', ], ],

Обновление viaTableAttributesValue

Настраиваем поведение в модели:

    public function behaviors()
    {
        return [
            [
                'class' => LinkerBehavior::class,
                'relations' => [
                    'roles' => [
                        'relatedRoles',
                        'updater' => [
                            'class' => ManyToManySmartUpdater::class,
                            'viaTableAttributesValue' => [
                                'created_at' => time(),
                            ],
                        ],
                    ],
                ],
            ],
        ];
    }

Я ожидаю, что поле created_at будет заполняться в базе только когда добавляется новая связь.
По факту получаю обновление поля при каждом сохранении модели, даже если связанные данные не менялись.

Действительно ли это то поведение, которое задумывалось? В моем примере такое поведение дает в итоге неверное значение времени создания связи.

Illegal string offset 'updater'

После замены ManyToMany на Linker behavior при сохранении модели появляется ошибка
Illegal string offset 'updater'

0001

Class 'yii\base\BaseObject' not found

Hi! Please help

"voskobovich/yii2-linker-behavior": "^4.0",
This is Yii version 2.0.12.2.

PHP Fatal Error – yii\base\ErrorException
Class 'yii\base\BaseObject' not found

  1. in www/vkr/vendor/voskobovich/yii2-linker-behavior/src/updaters/BaseUpdater.php

Дублирование запросов,страница обновления

Не могу понять в чем причина, на странице обновления когда вывожу форму,
например

            <?= $form->field($modelShop, 'category_ids')->widget(Select2::classname(), [
                'data' => \common\models\Category::getAllList(),
                'options' => ['placeholder' => 'Выбрать категории','multiple' => true],
                'pluginOptions' => [
                    'allowClear' => true
                ],
            ]); ?>

            <?= $form->field($modelShop, 'country_ids')->widget(Select2::classname(), [
                'data' => $countryListArray,
                'options' => ['placeholder' => 'Выбрать страны','multiple' => true],
                'pluginOptions' => [
                    'allowClear' => true
                ],
            ]); ?>

Каждое такое поле, выполняет аж 9 запросов.Из них 4 дублируется.
yii debugger

У меня 2 поля таких category_ids, regions_ids итого +18 запросов.

Я не пойму или я что то делаю не так, или в чем может быть проблема.

    public function behaviors() {
        return [
            'relation' => [
                'class' => LinkerBehavior::className(),
                'relations' => [
                    'country_ids' => [
                        'countries',
                        'updater' => [
                            'class' => ManyToManySmartUpdater::class,
                        ]
                    ],
                    'category_ids' => [
                        'categories',
                        'updater' => [
                            'class' => ManyToManySmartUpdater::class,
                        ]
                    ],
                ],
            ],
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getShopCategories() {
        return $this->hasMany(ShopCategory::className(), ['shop_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCategories() {
        return $this->hasMany(Category::className(), ['id' => 'category_id'])->via('shopCategories');
    }

Глобальний конфіг для Many-to-Many

Вітаю, чи є спосіб додати глобальний конфіг для використання ManyToManySmartUpdater для Many-to-Many зв'язків?
P.S. В доках відсутній приклад, як власне змінювати апдейтер.

'tags_ids' => 'tags',
// на
'tags_ids' => [
                        'tags',
                        'updater' => [
                            'class' => ManyToManySmartUpdater::className(),
                        ],
                    ],

error in ManyToManySmartUpdater

[
$junctionColumnName => $primaryModelPkValue,
$relatedColumnName => $untouchedKey,
]

There is an error in the above lines.
This is the correct code:

 $dbConnection->createCommand()
                        ->update(
                            $viaTableName,
                            $row,
                            ArrayHelper::merge(
                                [$junctionColumnName => $primaryModelPkValue],
                                [$relatedColumnName => $untouchedKey],
                                $this->getViaTableCondition()
                            )
                        )
                        ->execute();

Otherwise the update doesn't work on relations with on condition and produce an SQL error for duplicate keys.

I have also a question:
is there a way to only "update" some columns on "Processing untouched relations" part.
E.g. i have this updater

        'updater' => [
                        'class' => ManyToManySmartUpdater::className(),
                        'rowConditionClass' => 'voskobovich\linker\AssociativeRowCondition',
                        'viaTableAttributesValue' => [
                            'reviewer_type' =>  self::REVIEW_TYPE_INVIVIDUAL,
                            'created_at'    => Carbon::now('UTC')->toDateTimeString(),
                            'updated_at'    => Carbon::now('UTC')->toDateTimeString(),
                            'created_by'    => Yii::$app->user->id,
                            'updated_by'    => Yii::$app->user->id,
                        ],
                        'viaTableCondition' => [
                            'reviewer_type' =>  self::REVIEW_TYPE_INVIVIDUAL,
                        ],
                    ]

On insert the sql is correct.
When i remove an relation entry as well.
But for untouched relations the all attribute names are updated.

  • the reviewer_type (which isn't changed as its the viaTableCondition (but this is needed otherwise the insert would fail.)
  • created_at and created_by shouldn't be updated as well. But i don't know how to change the code that for the update scenario those aren't added to the update sql?

As you have isNewRecord in the AssociativeRowCondition there must be a way?

PHP 7.2 Support ?

Upgraded the PHP version on my server to the 7.2, but now running into some issues, can you look into this please ?

 Cannot use yii\base\Object as Object because 'Object' is a special class name in /var/www/site/html/vendor/voskobovich/yii2-linker-behavior/src/updaters/BaseUpdater.php on line 8
<pre>PHP Compile Error &#039;yii\base\ErrorException&#039; with message &#039;Cannot use yii\base\Object as Object because &#039;Object&#039; is a special class name&#039;

дополнительное поле в промежуточную таблицу

Здравствуйте. Написал сначала на форуме- попросили написать вам лично.
http://yiiframework.ru/forum/viewtopic.php?f=19&t=42879
Там же в форуме модель и таблицы описаны.

-------копия верхнего текста с форума----------------------------------
Можно ли добавлять дополнительное поле в промежуточную таблицу используя это поведение ? Что нужно прописать в Геттерах - зеттерах?
Поясню зачем .
1-я таблица это фильмы. У одного фильма может быть несколько режиссеров. Например Иванов АА, Борисов Б и Петров В , взятых из таблицы media_man.
А так же у одного фильма может быть несколько продюсеров . Тот же Иванов А.А и Петров. Они тоже взяты из таблицы media_man. Т.е в промежуточную таблицу нужен еще параметр- тип человека.

Есть вариант- сделать на каждый человека тип промежуточную таблицу- но это очень плохой вариант. Наиболее хороший- это добавить к промежуточной таблице(media_has_man) тройной ключ и поле c типом человека. Но я не уверен, что данное поведение обладает данным функционалом.
Замечу. Без дополнительного поля- поведение работает.

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

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); // []

Сброс кеша при обновлении

Есть у меня модель Base для объектов (отель, пансионат...) и Service (парк, бассейн, корт...) и связующая таблица {{%base_to_service}}.

Связь

public function getServices()
{
    return $this->hasMany(
        Service::className(),
        ['id' => 'service_id']
    )->viaTable(
        '{{%base_to_service}}',
        ['base_id' => 'id']
    );
}

Вывожу список объектов вместе с сервисами. Чтобы не дергать каждый раз сервисы - их кеширую через виджет.

Теперь, если изменить количество привязанных к объекту сервисов в админке, нужно инвалидировать кеш.

Как это лучше сделать?

Ошибка Relationship type is not supported.

При сохранении категорий у меня выдается ошибка "Relationship type is not supported."
Для того чтобы назначить родительскую категорию, я использую связь

public function getCategories()
    {
        return $this->hasOne(Categories::className(), ['id' => 'parent_id']);
    }

parent_id также хранится в таблице 'categories'

В модели прописано поведение (оно мне понадобится в дальнейшем):

public function behaviors()
    {
        return [
            [
                'class' => \voskobovich\linker\LinkerBehavior::className(),
                'relations' => [
                    'features_ids' => 'features',
                    'categories_ids' => 'categories'
                ],
            ],
        ];
    }
    public function rules()
    {
        return [
            [['name', 'price'], 'required'],
            [['parent_id'], 'integer'],
            [['price'], 'number'],
            [['formula'], 'string'],
            [['name', 'description'], 'string', 'max' => 255],
            [['features_ids', 'categories_ids'], 'each', 'rule' => ['integer']]
        ];
}

При чем категория сохраняется. Если не указывать родительскую категорию, то всё работает, также ошибка пропадает при удалении поведения.

Код ошибки


1. in \vendor\yiisoft\yii2\base\ErrorException.php at line 43
34353637383940414243444546474849505152     * Constructs the exception.
     * @link http://php.net/manual/en/errorexception.construct.php
     * @param $message [optional]
     * @param $code [optional]
     * @param $severity [optional]
     * @param $filename [optional]
     * @param $lineno [optional]
     * @param $previous [optional]
     */

    public function __construct($message = '', $code = 0, $severity = 1, $filename = __FILE__, $lineno = __LINE__, \Exception $previous = null)
    {
        parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
 
        if (function_exists('xdebug_get_function_stack')) {
            // XDebug trace can't be modified and used directly with PHP 7
            // @see https://github.com/yiisoft/yii2/pull/11723
            $xDebugTrace = array_slice(array_reverse(xdebug_get_function_stack()), 3, -1);
            $trace = [];
            foreach ($xDebugTrace as $frame) {

2. voskobovich\linker\LinkerBehavior::saveRelations(yii\db\AfterSaveEvent)

Работают ли behaviors в связывающей таблице (ManyToMany)?

Имеем три таблицы: Users, Groups и связывается все через таблицу UsersToGroups.
В таблице users_to_groups три поля:
user_id, group_id, created_by, updated_by
Соответственно, в модели UsersToGroups есть такое поведение:
'blameable' => [ 'class' => 'BlameableBehavior', ],
Связывающие поля заполняются как надо, а вот created_by и updated_by всегда пустые. Т.е. behaviors Не отрабатывают. Это фича или бага?

Документация для замены класса апдейтера

Было бы неплохо добавить в документацию пример замены на ManyToManySmartUpdater, напр.

use voskobovich\linker\LinkerBehavior;
use voskobovich\linker\updaters\ManyToManySmartUpdater;
// ...
            [
                'class' => LinkerBehavior::className(),
                'relations' => [
                    'review_ids' => [
                        'reviews',
                        'updater' => [
                            'class' => ManyToManySmartUpdater::class,
                        ]
                    ],
                ],
            ],

Мне понадобилось использовать метод научного тыка и анализ исходников (пусть и не сильно долго, но всё же), а кто-то вообще сам не смог разобраться, см. #10 (тот issue обнаружил лишь когда создавал этот).
А так отличное решение, спасибо.

Дополнительные поля в связующей таблице

Вопрос по функционалу.

Есть связующая таблица для many-to-many. В этой таблице есть еще пара полей, в которые нужно заносить информацию. Есть ли такой функционал в данном behavior, либо обрабатывать отдельно?

Спасибо

Useless fxp/composer-asset-plugin

Why this behaviour require "fxp/composer-asset-plugin": "*" ?

I think without require "fxp/composer-asset-plugin": "*" in your composer, yii2 actualy use this plugin as self or global plugin

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.