Intereting Posts
Пользовательская маршрутизация URI по строке запроса с помощью CodeIgniter? mysqli_fetch_array возвращает только один результат Функция Smarty Object с ассоциативным массивом Неожиданный «=>», ожидаемый один из: «», «», «)», Проблемы с добавлением набора столбцов базы данных в массив Как включить PHP-код в CSS? множественное автоматическое приращение в mysql PHP HSV для понимания формулы RGB Mysql_real_escape_string () Не удалось установить ссылку на сервер Что вызывает ошибку PDO Не удается выполнить запросы, в то время как другие небуферизованные запросы активны? Как проверить, является ли введенное значение валютой Извлечение файлов из .phar-архива Строгие стандарты: нестатический метод STemplate :: assign () не следует называть статически PHP: Как передать дочерние классы __construct () аргументам parent :: __ construct ()? Проверка уникальной электронной почты с помощью DynamicFormWidget – Yii2 ini_set () область действия?

Laravel: выполнение некоторых задач при каждой вставке / обновлении при использовании Query Builder или Eloquent ORM

Проблема

Я хотел бы автоматически добавлять поля created_by и modified_by в каждую вставку / обновление в таблицу базы данных в Laravel 4 независимо от того, использую ли я Eloquent или Query Builder. Однако не все мои таблицы имеют эти поля, поэтому любое решение должно проверять эти столбцы перед добавлением.

Попытка решения

Я расширил класс Illuminate\Database\Eloquent\Model и написал метод save() , чтобы добавить некоторые дополнительные поля метаданных для каждой сохраненной записи.

Это прекрасно, за исключением того, что если я выполняю вставку с помощью Query Builder, это обходит. Глядя на класс Model кажется, что операции с базой данных фактически выполняются с помощью построителя запросов.

Я взглянул на модель Illuminate\Database\Query\Builder и похоже, что я, вероятно, мог бы написать методы перезаписи для insert() и update() .

Является ли это разумным способом выполнения какой-либо задачи для каждой вставки / обновления или я буду сталкиваться с проблемами позже по линии?

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

Вы должны использовать функциональную функцию Model Events, которую eloquent предоставляет для этого.

Проще говоря, вам нужно определить событие сохранения для модели, чтобы переопределить / установить / проверить данные, которые модель собирается сохранить.

Простой пример для размещения класса модели User:

 //Executed when loading model public static function boot() { parent::boot(); User::creating(function($user){ $user->value1 = $user->value2 +1; }); } 

Дополнительная информация: http://four.laravel.com/docs/eloquent#model-events

Добавление к приведенным выше ответам. Вы могли бы сделать что-то подобное.

Создайте класс в приложении / модели под названием BaseModel.php, расширяющий \ Eloquent

 class BaseModel extends \Eloquent{ public static function boot() { parent::boot(); static::creating(function($model) { //change to Auth::user() if you are using the default auth provider $user = Confide::user(); $model->created_by = $user->id; $model->updated_by = $user->id; }); static::updating(function($model) { //change to Auth::user() if you are using the default auth provider $user = Confide::user(); $model->updated_by = $user->id; }); } } 

Затем в ваших индивидуальных классах моделей вам нужно расширить BaseModel вместо \ Eloquent

 class Product extends BaseModel { protected $table = 'product'; //Booting the base model to add created_by and updated_by to all tables public static function boot() { parent::boot(); } } 

Теперь, когда вы сохраняете или обновляете модель, автоматически создаются поля created_by и updated_by.

Примечание: Это будет работать только тогда, когда сохранение или обновление выполняется через Eloquent. Для построителя запросов у вас может быть общий метод для извлечения и добавления обновлений столбца created_by и update_by.

Если вы хотите использовать Query Builder, а Eloquent – единственный способ обойти это без расширения основных компонентов (что я не считаю необходимым), вы можете просто использовать Event System .

Ссылка: http://laravel.com/docs/events

Поэтому вы должны использовать событие, например user.custom.save , а затем создать функцию для использования с построителем запросов, который в конце будет запускать это событие, так же как и с Eloquent.

Пример:

 class User extends Eloquent { public function save() { Event::fire('user.custom.save', array($this)); parent::save(); } } 

В Laravel 5.3, если вы хотите называть один метод для каждого сохранения / обновления из одной точки без внесения каких-либо дополнительных изменений в каждую из расширенных моделей , вы можете иметь пользовательский прослушиватель для красноречивых событий. Как говорится в документации, это может быть сделано только для каждой модели. Но создание пользовательского прослушивателя позволяет получить доступ к любому событию в любой модели.

Просто добавьте метод EventServiceProvider to boot() в EventServiceProvider как EventServiceProvider ниже, и соответствующим образом измените.

 Event::listen(['eloquent.saving: *', 'eloquent.creating: *'], function(){ //your method content //returning false will cancel saving the model }); 

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

Вы можете использовать пакет ревизии для венчурного бизнеса, потому что в таблице из этого пакета все необходимые вам данные уже сохранены, вам просто нужен этот пакет, чтобы получить их элегантным способом: https://github.com/fico7489/laravel-revisionable-upgrade