Modelos inteligentes autovalidantes para Eloquent ORM de Laravel Framework 5.
Basado en el paquete Aware para Laravel 3 de Colby Rabideau.
Copyright (C) 2013-2015 Max Ehsan e Igor Santos
Visite nuestra lista de lanzamientos. El registro de cambios se realiza allí :)
Agregue laravelbook/ardent
como requisito a composer.json
(¡consulte nuestra última versión estable en las insignias!):
{"requerir": {"laravelbook/ardent": "3.*"}}
Actualice sus paquetes con composer update
o instálelos con composer install
.
También puedes agregar el paquete usando composer require laravelbook/ardent
y luego especificando la versión que deseas (por ahora, dev-master
es tu mejor opción).
Si desea utilizar Ardent como un paquete ORM independiente, está invitado a hacerlo utilizando la siguiente configuración en el archivo de arranque/inicio de su proyecto (cambiando las propiedades de acuerdo con su base de datos, obviamente):
LaravelArdentArdentArdent::configureAsExternal(array( 'controlador' => 'mysql', 'host' => 'localhost', 'puerto' => 3306, 'base de datos' => 'mi_sistema', 'nombre de usuario' => 'yo mismo', 'contraseña' => 'h4ckr', 'charset' => 'utf8', 'cotejo' => 'utf8_unicode_ci'), 'es'); //El inglés es el idioma predeterminado para los mensajes, puede dejarse vacío
Introducción
Empezando
Validación sin esfuerzo con Ardent
Recuperar errores de validación
Validación primordial
Mensajes de error de validación personalizados
Reglas de validación personalizadas
Ganchos modelo
Definición más limpia de relaciones
Hidratar automáticamente entidades ardientes
Purgar automáticamente datos de formulario redundantes
Transforme automáticamente los atributos de texto seguro
Actualizaciones con reglas únicas
¿Con qué frecuencia te encuentras recreando el mismo código repetitivo en las aplicaciones que creas? ¿Le resulta demasiado familiar este código típico de procesamiento de formularios?
Ruta::post('register', function() {$rules = array('nombre' => 'requerido|entre:3,80|alpha_dash','email' => 'requerido|entre:5,64|correo electrónico |único:usuarios','contraseña' => 'requerido|min:6|confirmado','contraseña_confirmación' => 'requerido|min:6');$validador = Validador::make(Input::all(), $reglas);if ($validador->pases()) { Usuario::create(array('nombre' => Entrada::get('nombre'),'correo electrónico' => Entrada::get('correo electrónico'),'contraseña' => Hash::make(Entrada:: obtener('contraseña')) ));return Redirect::to('/')->with('message', '¡Gracias por registrarte!'); } else {return Redirect::to('/')->withErrors($validator->getMessages()); } } );
Implementar esto usted mismo a menudo resulta en una gran cantidad de código repetitivo repetido. Como beneficio adicional, sus controladores (o manejadores de rutas) engordan prematuramente y su código se vuelve confuso, feo y difícil de entender.
¿Qué pasaría si alguien más hiciera todo el trabajo pesado por ti? ¿Qué pasaría si, en lugar de regurgitar el lío anterior, todo lo que necesitaras escribir fueran estas pocas líneas?...
Ruta::post('register', function() {$usuario = nuevo Usuario;if ($usuario->save()) {return Redirect::to('/')->with('mensaje', 'Gracias para registrarse!'); } else {return Redirect::to('/')->withErrors($usuario->errors()); } } );
¡Entra Ardiente!
Ardent : ¡la solución integral, fácil de usar y que funciona con polvo mágico para todas tus aburridas rutinas de desinfección!
Dejando a un lado los juegos de palabras, la funcionalidad de validación de entradas puede volverse rápidamente tediosa de escribir y mantener. Ardent soluciona estas complejidades proporcionando ayudas para automatizar muchas tareas repetitivas.
Sin embargo, Ardent no sólo es excelente para la validación de entradas: le ayudará a reducir significativamente el código del modelo de datos de Eloquent. Ardent es particularmente útil si te cansas de escribir código muy similar una y otra vez en múltiples aplicaciones individuales.
Por ejemplo, el registro de usuario o el envío de publicaciones de blog es un requisito de codificación común que quizás desee implementar en una aplicación y reutilizar nuevamente en otras aplicaciones. Con Ardent, puede escribir sus modelos inteligentes y conscientes de sí mismo solo una vez y luego reutilizarlos (con muy poca o ninguna modificación) en otros proyectos. Una vez que te acostumbres a esta forma de hacer las cosas, honestamente te preguntarás cómo te las arreglaste sin Ardent.
¡No más lesiones por tensión cerebral repetitivas para usted!
Ardent
pretende ampliar la clase base Eloquent
sin cambiar su funcionalidad principal. Dado que Ardent
en sí es descendiente de IlluminateDatabaseEloquentModel
, todos sus modelos Ardent
son totalmente compatibles con Eloquent
y pueden aprovechar todo el poder del increíble OR/M de Laravel.
Para crear un nuevo modelo Ardent, simplemente haga que la clase de su modelo derive de la clase base Ardent
. En los siguientes ejemplos usaremos la clase con espacio de nombres completo para que los ejemplos sean más limpios, pero te recomendamos que utilices use
en todas tus clases:
utilizar LaravelArdentArdentArdent; clase Usuario extiende Ardent {}
Nota: Puedes combinar libremente tus modelos Eloquent básicos con descendientes Ardent. Si un objeto modelo no depende del contenido enviado por el usuario y, por lo tanto, no requiere validación, puede dejar la clase modelo Eloquent como está.
Los modelos Ardent utilizan la clase Validator incorporada de Laravel. Definir reglas de validación para un modelo es simple y normalmente se realiza en su clase de modelo como una variable estática:
clase Usuario extiende LaravelArdentArdentArdent { public static $rules = array('nombre' => 'requerido|entre:3,80|alpha_dash','email' => 'requerido|entre:5,64|correo electrónico|único:usuarios', 'contraseña' => 'requerido|min:6|confirmado','contraseña_confirmación' => 'requerido|min:6', ); }
Nota : también puedes utilizar la sintaxis de matriz para las reglas de validación. Espero que no le importe el antiguo enlace de documentos de Laravel, pero por muy buena que sea la documentación de Laravel, desafortunadamente la referencia clara sobre las sintaxis de canalización/matriz para las reglas de Validación ya no existe desde la versión 5.1.
Los modelos Ardent se validan automáticamente cuando se llama a Ardent->save()
.
$usuario = nuevo usuario;$usuario->nombre = 'John Doe';$usuario->correo electrónico = '[email protected]';$usuario->contraseña = 'prueba';$éxito = $usuario->save( ); // devuelve falso si el modelo no es válido
Nota: También puedes validar un modelo en cualquier momento usando el método
Ardent->validate()
.
Cuando un modelo Ardent no se valida, se adjunta un objeto IlluminateSupportMessageBag
al objeto Ardent que contiene mensajes de error de validación.
Recupere la instancia de recopilación de mensajes de errores de validación con el método Ardent->errors()
o la propiedad Ardent->validationErrors
.
Recupere todos los errores de validación con Ardent->errors()->all()
. Recupere errores para un atributo específico usando Ardent->validationErrors->get('attribute')
.
Nota: Ardent aprovecha el objeto MessagesBag de Laravel, que tiene un método simple y elegante para formatear errores.
Hay dos formas de anular la validación de Ardent:
forceSave()
valida el modelo pero lo guarda independientemente de si hay o no errores de validación.
tanto Ardent->save($rules, $customMessages)
como Ardent->validate($rules, $customMessages)
toman dos parámetros:
$rules
es una matriz de reglas del Validador de la misma forma que Ardent::$rules
.
Lo mismo ocurre con el parámetro $customMessages
(igual que Ardent::$customMessages
)
Una matriz que no esté vacía anulará las reglas o los mensajes de error personalizados especificados por la clase solo para esa instancia del método.
Nota: el valor predeterminado para
$rules
y$customMessages
esarray()
; por lo tanto, si pasa unaarray()
no se anulará nada.
Al igual que Laravel Validator, Ardent te permite configurar mensajes de error personalizados usando la misma sintaxis.
clase Usuario extiende LaravelArdentArdentArdent { public static $customMessages = array('required' => 'El campo :attribute es obligatorio.', ... ); }
Puede crear reglas de validación personalizadas de la misma manera que lo haría con Laravel Validator.
Ardent proporciona algo de azúcar sintáctico sobre los eventos del modelo de Eloquent: ganchos de modelo tradicionales. Son una forma sencilla de conectar operaciones adicionales a diferentes momentos de la vida de su modelo. Se pueden utilizar para realizar trabajos de limpieza adicionales antes de eliminar una entrada, realizar correcciones automáticas después de que se produzca la validación o actualizar modelos relacionados después de que se produzca una actualización.
Todo lo before
los ganchos, al devolver valores false
(específicamente booleanos, no simplemente "falsos") detendrá la operación. Entonces, por ejemplo, si desea dejar de guardar si algo sale mal en un método beforeSave
, simplemente return false
y el guardado no se realizará y, obviamente, tampoco se llamará afterSave
.
Aquí está la lista completa de ganchos disponibles:
before
/ afterCreate()
before
/ afterSave()
before
/ afterUpdate()
before
/ afterDelete()
before
/ afterValidate()
: cuando se devuelve false, se detendrá la validación, lo que hará que las operaciones save()
también fallen, ya que la validación fue un error.
Por ejemplo, puede usar beforeSave
para aplicar hash a la contraseña de un usuario (en realidad, ¡sería una mejor idea usar el hash automático!):
class Usuario extiende LaravelArdentArdentArdent { función pública beforeSave() {// si hay una nueva contraseña, hash itif($this->isDirty('contraseña')) { $this->contraseña = Hash::make($this->contraseña ); } devuelve verdadero;//o no devuelve nada, ya que sólo un valor booleano falso detendrá la operación } }
beforeSave
y afterSave
se pueden incluir en tiempo de ejecución. Simplemente pase cierres con el modelo como argumento al método save()
(o forceSave()
).
$usuario->save(array(), array(), array(), function ($model) { // cierre para beforeSaveecho "guardando el objeto modelo...";return true; }, función ($modelo) { // cierre para afterSaveecho "¡listo!"; } );
Nota: los cierres deben tener un parámetro, ya que se le pasará una referencia al modelo que se guarda.
¿Alguna vez has escrito un modelo Eloquent con un montón de relaciones, sólo para darte cuenta de lo abarrotada que está tu clase, con todas esas frases ingeniosas que tienen casi el mismo contenido que el nombre del método?
En Ardent puedes definir limpiamente tus relaciones en una matriz con su información, y funcionarán como si las hubieras definido en métodos. He aquí un ejemplo:
clase Usuario extiende LaravelArdentArdentArdent { public static $relationsData = array('address' => array(self::HAS_ONE, 'Dirección'),'orders' => array(self::HAS_MANY, 'Order'),'groups' = > matriz(self::BELONGS_TO_MANY, 'Grupo', 'tabla' => 'grupos_tienen_usuarios') ); }$usuario = Usuario::find($id);echo "{$usuario->dirección->calle}, {$usuario->dirección->ciudad} - {$usuario->dirección->estado}";
La sintaxis de la matriz es la siguiente:
Primer valor indexado: nombre de la relación, siendo uno de hasOne
, hasMany
, belongsTo
, belongsToMany
, morphTo
, morphOne
, morphMany
o una de las constantes relacionadas ( Ardent::HAS_MANY
o Ardent::MORPH_ONE
por ejemplo).
Segundo indexado: nombre de la clase, con espacio de nombres completo. La excepción son las relaciones morphTo
, que no requieren argumentos adicionales.
argumentos con nombre, siguiendo los definidos para los métodos originales de Eloquent:
foreignKey
[opcional], válida para hasOne
, hasMany
, belongsTo
y belongsToMany
table
, otherKey
[opcional], timestamps
[booleanas, opcionales] y pivotKeys
[matriz, opcional], válidas para belongsToMany
name
, type
e id
, utilizados por morphTo
, morphOne
y morphMany
(los dos últimos requieren que se defina name
)
Nota: Esta función se basó en las relaciones sencillas de Yii 1.1 ActiveRecord.
¡Ardent es capaz de hidratar automáticamente la clase de modelo de entidad desde el envío de entrada del formulario!
Veámoslo en acción. Considere este fragmento de código:
$usuario = nuevo Usuario;$usuario->nombre = Entrada::get('nombre');$usuario->correo electrónico = Entrada::get('correo electrónico');$usuario->contraseña = Hash::make(Entrada ::get('contraseña'));$usuario->guardar();
Invoquemos la magia de Ardent y reescribamos el fragmento anterior:
$usuario = nuevo usuario;$usuario->save();
¡Eso es todo! Todo lo que hemos hecho es eliminar las cosas aburridas.
Lo creas o no, el código anterior realiza esencialmente la misma tarea que su hermano mayor, aunque bastante detallado. Ardent completa el objeto modelo con atributos de los datos del formulario enviados por el usuario. Ya no tendrás que tirarte de los pelos tratando de descubrir qué propiedad de Eloquent has olvidado completar. ¡Deja que Ardent se encargue de las cosas aburridas, mientras tú sigues con las cosas divertidas!
Sigue las mismas reglas de asignación masiva internamente, dependiendo de las propiedades $fillable
/ $guarded
.
Para habilitar la función de hidratación automática, simplemente establezca la variable de instancia $autoHydrateEntityFromInput
en true
en su clase de modelo. Sin embargo, para evitar que se llenen propiedades preexistentes, si desea la hidratación automática también para escenarios de actualización, debe usar $forceEntityHydrationFromInput
:
clase Usuario extiende LaravelArdentArdentArdent { public $autoHydrateEntityFromInput = true; // se hidrata en la validación de nuevas entradas público $forceEntityHydrationFromInput = verdadero; // se hidrata cada vez que se llama a la validación}
Los modelos Ardent pueden purgar automáticamente y por arte de magia datos de entrada redundantes (como confirmación de contraseña , _token
CSRF oculto o campos _method
HTTP personalizados), de modo que los datos adicionales nunca se guarden en la base de datos. Ardent utilizará los campos de confirmación para validar la entrada del formulario y luego descartará prudentemente estos atributos antes de guardar la instancia del modelo en la base de datos.
Para habilitar esta característica, simplemente configure la variable de instancia $autoPurgeRedundantAttributes
en true
en su clase de modelo:
clase Usuario extiende LaravelArdentArdentArdent { public $autoPurgeRedundantAttributes = true; }
También puede eliminar campos adicionales. El atributo Ardent::$purgeFilters
es una matriz de cierres a los que puede agregar sus reglas personalizadas. Esos cierres reciben la clave del atributo como argumento y deben devolver false
para los atributos que deben eliminarse. Como esto:
función __construct($atributos = matriz()) { padre::__construct($atributos); $this->purgeFilters[] = function($key) {$purge = array('tempData', 'myAttribute');return! in_array($clave, $purga); }; }
Suponga que tiene un atributo llamado password
en su clase de modelo, pero no desea almacenar la versión de texto sin formato en la base de datos. Lo pragmático sería almacenar el hash del contenido original. ¡No te preocupes, Ardent es totalmente capaz de transformar automáticamente cualquier número de campos seguros para ti!
Para hacer eso, agregue el nombre del atributo a la variable de matriz estática Ardent::$passwordAttributes
en su clase de modelo y establezca la variable de instancia $autoHashPasswordAttributes
en true
:
clase Usuario extiende LaravelArdentArdentArdent { public static $passwordAttributes = array('contraseña'); público $autoHashPasswordAttributes = verdadero; }
Ardent reemplazará automáticamente el atributo de contraseña de texto plano con una suma de comprobación hash segura y lo guardará en la base de datos. Utiliza el método Laravel Hash::make()
internamente para generar hash. Nota: Se recomienda utilizar el atributo $hidden
de Eloquent para que la contraseña, incluso con hash, no salga tan fácilmente si estás creando una API o similar :)
En caso de que esté utilizando Ardent de forma independiente, puede usar Ardent::$hasher
para verificar el valor del campo, usando algo como User::$hasher->check($given_password, $user->password)
.
Ardent puede ayudarle con actualizaciones únicas. Según la documentación de Laravel, cuando actualiza (y por lo tanto valida) un campo con una regla única, debe pasar el ID único del registro que está actualizando. Sin pasar este ID, la validación fallará porque el Validador de Laravel pensará que este registro es un duplicado.
De la documentación de Laravel:
'correo electrónico' => 'único:usuarios,correo electrónico,10'
En el pasado, los programadores tenían que gestionar manualmente la transferencia del ID y el cambio del conjunto de reglas para incluir el ID en tiempo de ejecución. No es así con Ardent. Simplemente configure sus reglas con la función de llamada unique
updateUniques
y Ardent se encargará del resto.
En su modelo extendido defina sus reglas
public static $rules = array( 'correo electrónico' => 'requerido|correo electrónico|único', 'contraseña' => 'requerido|entre:4,20|confirmado', 'contraseña_confirmación' => 'entre:4,20', );
En su controlador, cuando necesite actualizar, simplemente llame
$modelo->updateUniques();
Si es necesario, puede ejecutar reglas de paso para updateUniques
; de lo contrario, utilizará las reglas estáticas proporcionadas por su modelo.
Tenga en cuenta que en el ejemplo anterior de reglas, no le dijimos al Validador qué tabla o incluso qué campo usar como se describe en la Documentación de Laravel (es decir unique:users,email,10
). Ardent es lo suficientemente inteligente como para resolverlo. (Gracias al usuario de github @Sylph)