Самопроверяющиеся интеллектуальные модели для Eloquent ORM Laravel Framework 5.
На основе пакета Aware для Laravel 3 от Колби Рабидо.
Copyright (C) 2013-2015 Макс Эхсан и Игорь Сантос
Посетите наш список релизов. Список изменений сделан там :)
Добавьте laravelbook/ardent
в качестве требования к composer.json
(см. нашу последнюю стабильную версию на значках!):
{"require": {"laravelbook/ardent": "3.*"}}
Обновите свои пакеты с помощью composer update
или установите его с помощью composer install
.
Вы также можете добавить пакет, используя composer require laravelbook/ardent
, а затем указав нужную версию (на данный момент лучше всего использовать dev-master
).
Если вы хотите использовать Ardent как отдельный пакет ORM, вам предлагается сделать это, используя следующую конфигурацию в файле загрузки/запуска вашего проекта (очевидно, изменив свойства в соответствии с вашей базой данных):
LaravelArdentArdentArdent::configureAsExternal(array( 'driver' => 'mysql', 'host' => 'localhost', 'port' => 3306, 'database' => 'my_system', 'username' => 'myself', 'пароль' => 'h4ckr', 'кодировка' => 'utf8', 'сопоставление' => 'utf8_unicode_ci'), 'эн'); //Английский язык сообщений по умолчанию, можно оставить пустым
Введение
Начиная
Простая проверка с Ardent
Получение ошибок проверки
Переопределение проверки
Пользовательские сообщения об ошибках проверки
Пользовательские правила проверки
Модельные крючки
Более четкое определение отношений
Автоматически увлажнять пылкие сущности
Автоматически удалять избыточные данные формы
Автоматическое преобразование атрибутов защищенного текста
Обновления с уникальными правилами
Как часто вам приходится заново создавать один и тот же шаблонный код в приложениях, которые вы создаете? Этот типичный код обработки формы кажется вам слишком знакомым?
Route::post('register', function() {$rules = array('name' => 'обязательно|между:3,80|alpha_dash','email' => 'обязательно|между:5,64|электронной почтой |unique:users','password' => 'обязательно|мин:6|подтверждено','password_confirmation' => 'required|min:6');$validator = Validator::make(Input::all(), $rules);if ($validator->passes()) { User::create(array('name' => Input::get('name'),'email' => Input::get('email'),'password' => Hash::make(Input:: получить('пароль')) )); return Redirect::to('/')->with('message', 'Спасибо за регистрацию!'); } else {return Redirect::to('/')->withErrors($validator->getMessages()); } } );
Самостоятельная реализация часто приводит к большому количеству повторяющегося шаблонного кода. В качестве дополнительного бонуса ваши контроллеры (или обработчики маршрутов) преждевременно разжижаются, а ваш код становится беспорядочным, уродливым и трудным для понимания.
Что, если кто-то другой сделает за вас всю тяжелую работу? Что, если вместо того, чтобы повторять описанную выше путаницу, все, что вам нужно было бы набрать, — это несколько строк?...
Route::post('register', function() {$user = new User;if ($user->save()) {return Redirect::to('/')->with('message', 'Спасибо за регистрацию!»); } else {return Redirect::to('/')->withErrors($user->errors()); } } );
Входите Ардент!
Ardent — универсальное решение для всех ваших унылых шаблонов входной дезинфекции, работающее на волшебной пыли, удобное для запястий!
Если отбросить каламбуры, то функция проверки ввода может быстро стать утомительной в написании и сопровождении. Ardent решает эти сложности, предоставляя помощников для автоматизации многих повторяющихся задач.
Однако Ardent не только отлично подходит для проверки входных данных — он поможет вам значительно сократить код модели данных Eloquent. Ardent особенно полезен, если вы устали снова и снова писать очень похожий код в нескольких отдельных приложениях.
Например, регистрация пользователя или отправка записи в блоге — это распространенное требование к кодированию, которое вы можете реализовать в одном приложении и повторно использовать в других приложениях. С помощью Ardent вы можете написать свои самосознательные умные модели всего один раз, а затем повторно использовать их (без изменений или с очень небольшими изменениями) в других проектах. Как только вы привыкнете к такому способу ведения дел, вы честно задаетесь вопросом, как вы раньше справлялись без Ardent.
Больше никаких повторяющихся травм головного мозга!
Ardent
стремится расширить базовый класс Eloquent
не меняя его основные функции. Поскольку сам Ardent
является потомком IlluminateDatabaseEloquentModel
, все ваши модели Ardent
полностью совместимы с Eloquent
и могут использовать всю мощь потрясающего OR/M Laravel.
Чтобы создать новую модель Ardent, просто сделайте класс модели производным от базового класса Ardent
. В следующих примерах мы будем использовать полный класс с пространством имен, чтобы сделать примеры более понятными, но вам рекомендуется использовать use
во всех ваших классах:
используйте LaravelArdentArdentArdent;Пользователь класса расширяет Ardent {}
Примечание. Вы можете свободно смешивать свои простые ванильные модели Eloquent с потомками Ardent. Если объект модели не зависит от предоставленного пользователем контента и, следовательно, не требует проверки, вы можете оставить класс модели Eloquent как есть.
Модели Ardent используют встроенный класс Validator Laravel. Определить правила проверки для модели просто и обычно выполняется в классе модели как статическая переменная:
class User расширяет LaravelArdentArdentArdent { public static $rules = array('name' => 'required|between:3,80|alpha_dash','email' => 'required|between:5,64|email|unique:users', 'пароль' => 'требуется|мин:6|подтверждено','password_confirmation' => 'требуется|мин:6', ); }
Примечание . Вы также можете использовать синтаксис массива для правил проверки. Надеюсь, вы не возражаете против старой ссылки на документацию Laravel, но, как бы хороша ни была документация Laravel, четкая ссылка на синтаксис каналов/массивов для правил проверки, к сожалению, исчезла с версии 5.1.
Модели Ardent проверяют себя автоматически при вызове Ardent->save()
.
$user = новый пользователь;$user->name = 'Джон Доу';$user->email = '[email protected]';$user->пароль = 'test';$success = $user->save( ); // возвращает false, если модель недействительна
Примечание. Вы также можете проверить модель в любое время, используя метод
Ardent->validate()
.
Если модель Ardent не проходит проверку, к объекту Ardent присоединяется объект IlluminateSupportMessageBag
, который содержит сообщения об ошибке проверки.
Получите экземпляр коллекции сообщений об ошибках проверки с помощью метода Ardent->errors()
или свойства Ardent->validationErrors
.
Получите все ошибки проверки с помощью Ardent->errors()->all()
. Получите ошибки для определенного атрибута, используя Ardent->validationErrors->get('attribute')
.
Примечание. Ardent использует объект MessagesBag от Laravel, который имеет простой и элегантный метод форматирования ошибок.
Есть два способа переопределить проверку Ardent:
forceSave()
проверяет модель, но сохраняет ее независимо от наличия ошибок проверки.
оба Ardent->save($rules, $customMessages)
и Ardent->validate($rules, $customMessages)
принимают два параметра:
$rules
— это массив правил Валидатора той же формы, что и Ardent::$rules
.
То же самое относится и к параметру $customMessages
(так же, как Ardent::$customMessages
).
Массив, который не является пустым, будет переопределять правила или пользовательские сообщения об ошибках, указанные классом только для этого экземпляра метода.
Примечание. Значением по умолчанию для
$rules
и$customMessages
является пустойarray()
; таким образом, если вы передадитеarray()
ничего не будет переопределено.
Как и Laravel Validator, Ardent позволяет вам устанавливать собственные сообщения об ошибках, используя тот же синтаксис.
class User расширяет LaravelArdentArdentArdent { public static $customMessages = array('required' => 'Поле :attribute является обязательным.', ... ); }
Вы можете создавать собственные правила проверки так же, как и для Laravel Validator.
Ardent добавляет немного синтаксиса к модельным событиям Eloquent: традиционные хуки моделей. Это простой способ подключить дополнительные операции к различным моментам жизни вашей модели. Их можно использовать для дополнительной очистки перед удалением записи, выполнения автоматических исправлений после проверки или обновления связанных моделей после обновления.
Все before
перехваты при возврате false
(в частности, логических, а не просто «ложных» значений) останавливают операцию. Так, например, если вы хотите прекратить сохранение, если что-то пойдет не так в методе beforeSave
, просто return false
, и сохранение не произойдет - и, очевидно, afterSave
также не будет вызываться.
Вот полный список доступных хуков:
before
/ afterCreate()
before
/ afterSave()
before
/ afterUpdate()
before
/ afterDelete()
before
/ afterValidate()
— при возврате false проверка будет остановлена, что приведет к сбою операций save()
поскольку проверка завершилась неудачей.
Например, вы можете использовать beforeSave
для хеширования пароля пользователя (на самом деле, было бы лучше использовать автоматическое хеширование!):
class User расширяет LaravelArdentArdentArdent { public function beforeSave() {// если есть новый пароль, хешируйте itif($this->isDirty('password')) { $this->password = Hash::make($this->password ); } return true;//или ничего не возвращать, поскольку только логическое значение false остановит операцию } }
beforeSave
и afterSave
могут быть включены во время выполнения. Просто передайте замыкания с моделью в качестве аргумента методу save()
( forceSave()
).
$user->save(array(), array(), array(), function ($model) { // закрытие for beforeSaveecho "сохранение объекта модели..."; return true; }, function ($model) { // закрытие afterSaveecho "done!"; } );
Примечание. Замыкания должны иметь один параметр, так как ему будет передана ссылка на сохраняемую модель.
Вы когда-нибудь писали модель Eloquent с кучей отношений просто для того, чтобы заметить, насколько загроможден ваш класс всеми этими однострочниками, которые имеют почти то же содержание, что и само имя метода?
В Ardent вы можете четко определить свои отношения в массиве с их информацией, и они будут работать так же, как если бы вы определили их в методах. Вот пример:
class User расширяет LaravelArdentArdentArdent { public static $relationsData = array('address' => array(self::HAS_ONE, 'Address'),'orders' => array(self::HAS_MANY, 'Order'),'groups' = > array(self::BELONGS_TO_MANY, 'Группа', 'таблица' => 'groups_have_users') ); }$user = User::find($id);echo "{$user->адрес->улица}, {$user->адрес->город} - {$user->адрес->штат}";
Синтаксис массива следующий:
Первое индексированное значение: имя отношения, являющееся одним из hasOne
, hasMany
, belongsTo
, belongsToMany
, morphTo
, morphOne
, morphMany
или одной из связанных констант (например, Ardent::HAS_MANY
или Ardent::MORPH_ONE
).
Второй индекс: имя класса с полным пространством имен. Исключением являются отношения morphTo
, которые не принимают дополнительных аргументов.
именованные аргументы, соответствующие тем, которые определены для исходных методов Eloquent:
foreignKey
[необязательный], действителен для hasOne
, hasMany
, belongsTo
и belongsToMany
table
, otherKey
[необязательно], timestamps
[логическое значение, необязательно] и pivotKeys
[массив, необязательно], действительны для belongsToMany
name
, type
и id
, используемые morphTo
, morphOne
и morphMany
(последние два требуют определения name
)
Примечание. Эта функция основана на простых отношениях Yii 1.1 ActiveRecord.
Ardent способен автоматически выделять класс вашей модели сущности из ввода формы!
Давайте посмотрим на это в действии. Рассмотрим этот фрагмент кода:
$user = новый пользователь;$user->name = Input::get('name');$user->email = Input::get('email');$user->password = Hash::make(Input ::get('пароль'));$user->save();
Давайте воспользуемся магией Ardent и перепишем предыдущий фрагмент:
$user = новый пользователь;$user->save();
Вот и все! Все, что мы сделали, это убрали скучное.
Хотите верьте, хотите нет, но приведенный выше код выполняет по существу ту же задачу, что и его старший, хотя и довольно многословный брат. Ardent заполняет объект модели атрибутами из данных формы, отправленных пользователем. Больше не нужно тянуть за волосы, пытаясь выяснить, какое свойство Eloquent вы забыли заполнить. Позвольте Ardent позаботиться о скучных вещах, а вы займитесь интересными делами!
Внутренне он следует тем же правилам массового назначения, в зависимости от свойств $fillable
/ $guarded
.
Чтобы включить функцию автоматической гидратации, просто установите для переменной экземпляра $autoHydrateEntityFromInput
значение true
в классе модели. Однако, чтобы предотвратить заполнение уже существующих свойств, если вы хотите автоматическую гидратацию также и для сценариев обновления, вместо этого следует использовать $forceEntityHydrationFromInput
:
класс User расширяет LaravelArdentArdentArdent {public $autoHydrateEntityFromInput = true; // гидраты при проверке новых записей общественный $forceEntityHydrationFromInput = true; // увлажняется при каждом вызове проверки}
Модели Ardent могут автоматически удалять избыточные входные данные (например, подтверждение пароля , скрытый CSRF _token
или пользовательские поля HTTP _method
), так что лишние данные никогда не сохраняются в базе данных. Ardent будет использовать поля подтверждения для проверки ввода формы, а затем разумно отбросит эти атрибуты перед сохранением экземпляра модели в базе данных!
Чтобы включить эту функцию, просто установите для переменной экземпляра $autoPurgeRedundantAttributes
значение true
в классе модели:
класс User расширяет LaravelArdentArdentArdent {public $autoPurgeRedundantAttributes = true; }
Вы также можете очистить дополнительные поля. Атрибут Ardent::$purgeFilters
представляет собой массив замыканий, к которым вы можете добавлять свои собственные правила. Эти замыкания получают ключ атрибута в качестве аргумента и должны возвращать false
для атрибутов, которые необходимо очистить. Так:
функция __construct($attributes = array()) { родитель::__construct($attributes); $this->purgeFilters[] = function($key) {$purge = array('tempData', 'myAttribute');return ! in_array($key, $purge); }; }
Предположим, у вас есть атрибут с именем password
в классе модели, но вы не хотите хранить его текстовую версию в базе данных. Прагматичным решением было бы сохранить хеш исходного контента. Не волнуйтесь, Ardent полностью способен автоматически трансмогрифицировать любое количество защищенных полей!
Для этого добавьте имя атрибута в переменную статического массива Ardent::$passwordAttributes
в классе модели и установите для переменной экземпляра $autoHashPasswordAttributes
значение true
:
класс User расширяет LaravelArdentArdentArdent {public static $passwordAttributes = array('password'); общественный $autoHashPasswordAttributes = true; }
Ardent автоматически заменит атрибут пароля в виде простого текста безопасной контрольной суммой хэша и сохранит ее в базе данных. Он использует внутренний метод Laravel Hash::make()
для генерации хеша. Примечание. Рекомендуется использовать атрибут $hidden
Eloquent, чтобы пароль, даже хешированный, не был так легко получен, если вы создаете API или что-то подобное :)
Если вы используете Ardent автономно, вы можете использовать Ardent::$hasher
для проверки значения поля, используя что-то вроде User::$hasher->check($given_password, $user->password)
.
Ardent может помочь вам с уникальными обновлениями. Согласно документации Laravel, когда вы обновляете (и, следовательно, проверяете) поле с уникальным правилом, вы должны передать уникальный идентификатор обновляемой записи. Без передачи этого идентификатора проверка завершится неудачей, поскольку валидатор Laravel посчитает эту запись дубликатом.
Из документации Laravel:
'email' => 'уникальные:пользователи,адрес электронной почты,10'
Раньше программистам приходилось вручную управлять передачей идентификатора и изменением набора правил, чтобы включить идентификатор во время выполнения. С Ардентом все не так. Просто настройте свои правила с помощью unique
, вызовите функцию updateUniques
, а Ardent позаботится обо всем остальном.
В вашей расширенной модели определите свои правила
public static $rules = array( 'email' => 'required|email|unique', 'password' => 'required|between:4,20|confirmed', 'password_confirmation' => 'between:4,20', );
В вашем контроллере, когда вам нужно обновить, просто вызовите
$модель->updateUniques();
При необходимости вы можете передать правила во время выполнения updateUniques
, в противном случае будут использоваться статические правила, предоставленные вашей моделью.
Обратите внимание, что в приведенном выше примере правил мы не указали валидатору, какую таблицу или даже какое поле использовать, как описано в документации Laravel (т. е. unique:users,email,10
). Ардент достаточно умен, чтобы понять это. (Спасибо пользователю github @Sylph)