ruby-on-rails validation activemodel

ruby on rails - ¿Una forma eficiente de reportar las advertencias de validación de registros así como los errores?



ruby-on-rails validation (1)

Aquí hay un código que escribí para un proyecto de Rails 3 que hace exactamente lo que estás hablando aquí.

# Define a "warnings" validation bucket on ActiveRecord objects. # # @example # # class MyObject < ActiveRecord::Base # warning do |vehicle_asset| # unless vehicle_asset.description == ''bob'' # vehicle_asset.warnings.add(:description, "should be ''bob''") # end # end # end # # THEN: # # my_object = MyObject.new # my_object.description = ''Fred'' # my_object.sensible? # => false # my_object.warnings.full_messages # => ["Description should be ''bob''"] module Warnings module Validations extend ActiveSupport::Concern include ActiveSupport::Callbacks included do define_callbacks :warning end module ClassMethods def warning(*args, &block) options = args.extract_options! if options.key?(:on) options = options.dup options[:if] = Array.wrap(options[:if]) options[:if] << "validation_context == :#{options[:on]}" end args << options set_callback(:warning, *args, &block) end end # Similar to ActiveModel::Validations#valid? but for warnings def sensible? warnings.clear run_callbacks :warning warnings.empty? end # Similar to ActiveModel::Validations#errors but returns a warnings collection def warnings @warnings ||= ActiveModel::Errors.new(self) end end end ActiveRecord::Base.send(:include, Warnings::Validations)

Los comentarios en la parte superior muestran cómo usarlo. Puede poner este código en un inicializador y luego las advertencias deberían estar disponibles para todos sus objetos ActiveRecord. Y luego, básicamente, solo agregue un bloque de warnings do en la parte superior de cada modelo que pueda tener advertencias y solo agregue manualmente todas las advertencias que desee. Este bloque no se ejecutará hasta que llame a .sensible? en el modelo

Además, tenga en cuenta que dado que las advertencias no son errores de validación, un modelo seguirá siendo técnicamente válido incluso si no es "sensible" (como lo llamé).

Tengo un proyecto de Rails en el que, como en la mayoría de las aplicaciones, tenemos una serie de reglas de validación estrictas que todos los objetos deben cumplir antes de persistir. Naturalmente, las Validaciones de ActiveModel son perfectas para eso, estamos usando una combinación de valores predeterminados de Rails y nuestras propias validaciones manuales.

Sin embargo, cada vez más nos enfrentamos a casos de uso en los que nos gustaría alertar al usuario sobre casos en los que, si bien sus datos no son válidos en el sentido más estricto, hay elementos que deberían revisar, pero que no deberían en sí mismos evitan que ocurra la persistencia de registros. Un par de ejemplos, fuera de mi cabeza:

  • Se ha enviado un título de publicación en TODAS LAS CAPS, que puede ser válido pero probablemente no lo sea
  • Un pice de texto del cuerpo es más que x número de palabras menos o más que una cantidad sugerida de palabras

El módulo de validaciones es una buena metáfora de cómo tratamos los errores de validación, y ya tiene tantos emparejadores disponibles, que idealmente me gustaría poder reutilizar ese código básico, pero generar una colección de elementos de warnings junto con los errors . Esto nos permitiría resaltar esos casos de manera diferente a nuestros usuarios, en lugar de dar a entender que las posibles violaciones del estilo de la casa son equivalentes a normas más estrictas y estrictamente aplicadas.

He visto gemas como activemodel-warnings , pero funcionan modificando qué concordantes se comprueban cuando se valida el registro, ampliando o reduciendo la colección de errors consecuencia. De manera similar, miré :on parámetro integrado en :on parámetro de validaciones para ver si podía entregar algo, pero nuevamente, todas las violaciones terminarán en una colección de errores en lugar de separarse.

¿Alguien ha intentado algo similar? No puedo imaginarme que soy el único que quisiera lograr este objetivo, pero me estoy quedando en blanco ahora mismo ...