Los datos es una gran cosa, pero los datos incorrectos pueden ser muy, muy malos. Por suerte, si eres un programador de Ruby on Rails, tienes a tu disposición una bonita API de ayudantes de validación ActiveRecord.
Esta guía es una exploración de validaciones de ActiveRecord comunes y no tan comunes en una aplicación Ruby on Rails dada. ¡Úselo para ayudar a mantener sus bases de datos felices!
¿Por qué usar validaciones?
Para garantizar que solo se guarden datos válidos en su base de datos. Además de la validación en el lado del cliente, las validaciones a nivel de modelo proporcionan una capa adicional de seguridad para todos y cada uno de los campos de formulario dentro de una aplicación Ruby on Rails.
Puede proporcionar validaciones en una variedad de niveles, pero todos tienen sus fortalezas y debilidades.
- Restricciones de base de datos: Las restricciones únicas a nivel de base de datos no permiten campos ni columnas duplicados si es necesario. Esto puede ir mucho más allá de la singularidad. es decir, valores predeterminados, restricciones no nulas, rangos, etc…
- Validación del lado del cliente: son útiles visualmente y proporcionan una mejor experiencia de usuario, pero a menudo no son confiables. Casi siempre proporcionaría un plan de respaldo usando este enfoque como se debe.
- Nivel de modelo (Rails) – ¡De lo que estamos hablando ahora!
- Nivel de controlador (Rieles): tentador de usar, pero más difícil de probar y mantener. Es una convención/práctica recomendada mantener los controladores lo más ligeros posible.
¿Cuándo se produce realmente la validación?
Directamente de la documentación de ruby on rails:
Hay dos tipos de objetos de Registro activo: los que corresponden a una fila dentro de la base de datos y los que no. Cuando crea un objeto nuevo, por ejemplo, utilizando el método
new
, ese objeto aún no pertenece a la base de datos. Una vez que llame asave
sobre ese objeto, se guardará en la tabla de base de datos adecuada. Active Record utiliza el método de instancianew_record?
para determinar si un objeto ya está en la base de datos o no.
Crear una nueva clase de Registro activo nos da la oportunidad de usar un método new_record?
para resolver todo esto.
class Article < ApplicationRecordend
Al hacerlo, podemos pulsar rails console
para localizar el proceso.
$ rails console>> article = Article.new(title: "My Article")=> #<Article id:nil title: "My Article", created_at: nil, updated_at: nil>>> article.new_record?=> true>> article.save=> true>> article.new_record?=> false
En realidad llamar a save
es lo que lo confirma en la base de datos y crea entre bastidores las instrucciones SQL
necesarias para hacerlo. Como resultado, las validaciones normalmente se ejecutan antes de enviar datos a la base de datos por completo.
Los siguientes métodos envoke validaciones sobre el uso:
create
create!
save
save!
update
update!
La explosión versiones (por ejemplo
save!
) elevar una excepción si el registro no es válido. Las versiones sin explosión no:save
yupdate
regresarfalse
ycreate
sólo devuelve el objeto.
Los métodos que omiten validaciones
Utilizando cualquiera de los siguientes omitirán validaciones por completo. ¡Use con precaución los datos valiosos!
decrement!
decrement_counter
increment!
increment_counter
toggle!
touch
update_all
update_attribute
update_column
update_columns
update_counters
Validation helpers
What I love about Ruby on Rails is the bundled goodness you get for doing pretty hard things. Los ayudantes de validación son una de esas cosas que me hacen sentir cálido y acogedor al implementar una nueva aplicación en la naturaleza. Esto proporciona una gran cantidad de soporte para una amplia gama de datos que puede estar recopilando del lado del cliente.
Cada ayudante acepta un :on
y :message
opción. Estas opciones definen cuándo se debe ejecutar la validación y qué mensaje se debe agregar a una colección errors
si falla (puede usarlas para ayudar a inyectar lo que está mal dentro de sus vistas para que el usuario sepa qué cambiar/alterar).
Hay un montón de ayudantes de validación, a continuación se muestran algunos de los más utilizados. Consulte la guía sobre validaciones de registros activos para obtener más casos de uso.
Confirmación
Útil para validar cuando dos campos de texto necesitan tener la misma entrada. Piense en un correo electrónico de confirmación, por ejemplo.
class User < ApplicationRecord validates :email, confirmation: trueend
Ahora, en su opinión, puede tener dos campos:
<%= text_field :user, :email %><%= text_field :user, :email_confirmation %>
Uno de gotcha aquí es que esta validación sólo se realiza si el presence
opción se establece en true en el modelo.
Por lo tanto, el modelo User
recibe una actualización:
class User < ApplicationRecord validates :email, confirmation: true validates :email_confirmation, presence: true end
Exclusión
Si necesita reservar alguna palabra o asegurarse de que una entrada determinada sea única, use exclusion
.
class Profile < ApplicationRecord validates :username, exclusion: { in: %w(username1 username2 username3), message: "%{value} has already been taken." }end
Observe cómo solía :message
aquí también. Esto se proporciona en todos los ayudantes de validación.
También puede usar inclusion
de la manera opuesta. ¡Consulte los documentos para obtener más información!
Formato
Las cadenas de formato a veces son ideales para tu app. Puedes usar expresiones regulares dentro de validaciones para alterar lo que buscas.
class Plan < ApplicationRecord validates :plan_type, format: { with: /\A+\z/, message: "Plans can only inlude letters"}end
Length
Uso este todo el tiempo para poner una restricción a la longitud de caracteres de un campo determinado.
class User < ApplicationRecord validates :name, length: { minimum: 5 } # sets a minimum validates :bio, length: { maximum: 500 } # sets a maximum validates :handle, length: { in: 5..16 } # provide a rangeend
Siéntase libre de personalizar los mensajes con la etiqueta :message
aquí también. Los siguientes están disponibles para conectarse para personalizar el mensaje.
wrong_length
too_long
-
too_short
Ejemplo
class User < ApplicationRecord validates :bio, length: { maximum: 800, too_long: "%{count} characters is the maximum." }end
Presencia
Este es probablemente el más ampliamente utilizado ayudante en mi bolsa de herramientas. Presencia comprueba que los campos no estén vacíos.
class User < ApplicationRecord validates :name, :email, presence: trueend
También puede probar que existe una asociación en los modelos
class Article < ApplicationRecord belongs_to :user validates :user, presence: true # looks for a user_id field on the articleend
En el modelo opuesto, puede hacer lo mismo con una captura llamada inverse_of
class User < ApplicationRecord has_many :articles, inverse_of: :userend
Unicidad
¿Tal vez quieras nombres de usuario únicos en tu aplicación? La singularidad ayuda con eso.
class User < ApplicationRecord validates :username, uniqueness: true, { message: "Username already taken" }end
Esto en realidad busca la etiqueta User
tabla de registros existentes para determinar uniqueness
Usted puede ir más allá y limitar el uniqueness
abajo a un scope
.
class User < ApplicationRecord validates :plan, uniqueness: { scope: :year, message: "can only update one per year"}end
Validaciones condicionales
A veces solo necesita validar dentro de determinadas condiciones. Puede realizar condicionales utilizando un enfoque como el siguiente.
class Purchase < ApplicationRecord validates :card_number, presence: true, if: :paid_with_card? def paid_with_card? payment_type == "card" endend
¿Necesita agrupar varias condiciones? Puedes hacer eso
class User < ApplicationRecord with_options if: :is_admin? do |admin| admin.validates :location, length: { minimum: 10 } admin.validates :job_title, presence: true endend
Métodos personalizados
A veces los ayudantes no son suficientes y es posible que necesites algo más personalizado. Puedes crear tus propios métodos que hagan algunas validaciones que hagas tú mismo.
class Invoice < ApplicationRecord validate :active_subscriber, on: :create def active_customer errors.add(:customer_id, "is not active") unless subscriber.active? endend
Nota aquí estoy validando este método usando la opción :on
que le permite determinar dónde inicializar la validación. En este caso elegí :create
.
También puede conectarse a la colección errors
, ya que tengo que modificar qué salidas en el lado del cliente si es necesario. No tenemos el :message
en métodos personalizados en este caso. Lee más sobre errores.
Palabras finales
Con suerte, las validaciones han abierto algunas ideas para que tu aplicación sea más restringida (en el buen sentido). El uso de Ruby on Rails y todas sus facetas permite que los datos seguros ingresen a cualquier base de datos de su elección. Desde tokens CSRF hasta validaciones a nivel de base de datos, hay un sinfín de formas de mejorar que su aplicación pueda mantener la calma sobre los datos que ingresan.
¡Enchufe Desvergonzado!
Si te gustó este post, tengo más videos en YouTube y aquí en mi blog. Quieren más contenido como este en tu bandeja de entrada? Suscríbete a mi boletín y recíbelo automáticamente.
Echa un vistazo a mi curso
☝ Quieren aprender Ruby on Rails desde cero? Echa un vistazo a mi próximo curso llamado Hello Rails.