Comprender las validaciones de ActiveRecord de Ruby on Rails

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 a save sobre ese objeto, se guardará en la tabla de base de datos adecuada. Active Record utiliza el método de instancia new_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 y update regresar false y create 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

https://i.imgur.com/KIaaJEB.jpg

☝ Quieren aprender Ruby on Rails desde cero? Echa un vistazo a mi próximo curso llamado Hello Rails.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.