Я имею дело с проблемой для Yii2 при добавлении TimestampBehavior для запуска из основной конфигурации. Причина в том, что я должен использовать его во внешнем интерфейсе и бэкэнде на большинстве моих моделей.
Использовать его в модели просто:
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => function(){ return date('Y-m-d H:i:s'); } ,
],
];
}
Но если я пытаюсь добавить поведение в main.php, ничего не происходит.
Я думал о:
'as timestamp'=>[
'class'=> \yii\behaviors\TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => function(){ return date('Y-m-d H:i:s'); } ,
],
Но это не работает. Есть идеи?
Если вы не хотите использовать наследование, я могу предложить следующий метод.
Основная идея заключается в использовании событий ActiveRecord
:
use yii\base\Event;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
...
$events = [ActiveRecord::EVENT_BEFORE_INSERT, ActiveRecord::EVENT_BEFORE_UPDATE];
foreach ($events as $eventName) {
Event::on(ActiveRecord::className(), $eventName, function ($event) {
$model = $event->sender;
if ($model->hasAttribute('created_at') && $model->hasAttribute('updated_at')) {
$model->attachBehavior('timestamp', [
'class' => TimestampBehavior::className(),
'value' => function () {
return date('Y-m-d H:i:s');
},
]);
}
});
}
Этот код будет динамически прикрепляться TimestampBehavior
для всех моделей, которые унаследованы от yii\db\ActiveRecord
перед сохранением в базу данных.
Вы также можете опустить createdAtAttribute
а также updatedAtAttribute
потому что они уже имеют эти имена по умолчанию (так как это наиболее часто встречается).
Как видите, поведение привязано только тогда, когда оба created_at
а также updated_at
атрибуты существуют, для этого не нужно создавать расширенное поведение.
Чтобы избежать наследования и копирования / вставки, этот код должен запускаться при каждой загрузке приложения.
Вы можете сразу добавить это в сценарий ввода (перед запуском приложения), и он будет работать, но не рекомендуется размещать его здесь, также эти файлы генерируются автоматически и в списке игнорируемых файлов git.
Поэтому вам нужно создать только один отдельный компонент, содержащий эту логику, и включить его в конфигурацию. Нет необходимости расширять классы и т. Д.
Допустим, это называется common\components\EventBootstrap
, Он должен реализовать BootstrapInterface
для того, чтобы работать правильно.
namespace common\components;
// Other namespaces from previous code
use yii\base\BootstrapInterface;
class EventBootstrap implements BootstrapInterface
{
public function bootstrap($app)
{
// Put the code above here
}
}
Затем вам нужно включить его в config в разделе начальной загрузки:
return [
'bootstrap' => [
'common\components\EventBootstrap',
],
];
Официальная документация:
Дополнительные примечания: Я также пытался указать это только через конфигурацию приложения, но безуспешно.
Я не нашел способ указать ActiveRecord
там.
Ты можешь видеть этот вопрос, но поведение там привязано ко всему приложению, что возможно через config.
Я знаю, что это немного старый вопрос, но если у кого-то возникла такая же проблема, я поделюсь тем, что нашел, как чистым способом сделать это. Я просто определяю поведение по признаку. Затем я просто использую эту черту в моделях, вот и все. Он добавляет только одну строчку в модель, но все же чище и делает обслуживание кода немного проще.
Вот примерная черта
<?php
namespace common\traits;
use Yii;
use yii\behaviors\BlameableBehavior;
use yii\behaviors\TimestampBehavior;
trait Signature
{
public function behaviors()
{
return [
[
'class' => BlameableBehavior::className(),
'createdByAttribute' => 'created_by',
'updatedByAttribute' => 'updated_by',
],
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' =>function(){
return time();
},
],
];
}
}
И код модели
class Category extends \yii\db\ActiveRecord
{
use \common\traits\Signature;
// Model code here
}