2010-07-27 13 views
9

Quiero ser capaz de reemplazar un error de campo con una advertencia al guardar/actualizar un modelo en rieles. Básicamente quiero escribir sólo una envoltura alrededor de los métodos de validación que va a generar el error, guardar el modelo y quizás esté disponible en un hash advertencias (que funciona igual que el hash errores):ActiveRecord - reemplace el error de validación del modelo con advertencia

class Person < ActiveRecord::Base 
    # normal validation 
    validates_presence_of :name 

    # validation with warning 
    validates_numericality_of :age, 
          :only_integer => true, 
          :warning => true # <-- only warn 
end 

>>> p = Person.new(:name => 'john', :age => 2.2) 
>>> p.save 
=> true # <-- able to save to db 
>>> p.warnings.map { |field, message| "#{field} - #{message}" } 
["age - is not a number"] # <-- have access to warning content 

Cualquier idea de cómo Podría implementar esto? Pude agregar el valor predeterminado de :warning => false a ActiveRecord::Validations::ClassMethods::DEFAULT_VALIDATION_OPTIONS Extendiendo el módulo, pero estoy buscando información sobre cómo implementar el resto. Gracias.

Respuesta

4

No sé si está listo para Rails 3, pero este plugin hace lo que busca:

http://softvalidations.rubyforge.org/

Editado para añadir:

Para actualizar la funcionalidad básica de este con ActiveModel me ocurrió lo siguiente:

#/config/initializer/soft_validate.rb: 
module ActiveRecord 
    class Base 
    def warnings 
     @warnings ||= ActiveModel::Errors.new(self) 
    end 
    def complete? 
     warnings.clear 
     valid? 
     warnings.empty? 
    end 
    end 
end 

#/lib/soft_validate_validator.rb 
class SoftValidateValidator < ActiveModel::EachValidator 
    def validate(record) 
    record.warnings.add_on_blank(attributes, options) 
    end 
end 

Se añade un nuevo errores l el objeto ike llamado warnings y un método auxiliar completo?, y se puede añadir a un modelo de este modo:

class FollowupReport < ActiveRecord::Base 
    validates :suggestions, :soft_validate => true 
end 
4

El validation_scopes gem utiliza algún buen magia metaprogramming para darle toda la funcionalidad habitual de las validaciones y objetos ActiveRecord :: Errores en contextos distintos object.errors .

Por ejemplo, puede decir:

validation_scope :warnings do |s| 
    s.validates_presence_of :some_attr 
end 

La validación anterior se disparará como es habitual en object.valid ?, pero no bloqueará guarda en la base de datos de object.save si some_attr no está presente . Cualquier objeto ActiveRecord :: Errors asociado se encontrará en object.warnings.

Las validaciones especificadas de la manera habitual sin un ámbito seguirán comportándose como se espera, bloqueando la base de datos guardando y asignando objetos de error a object.errors.

El autor tiene una breve descripción del desarrollo de la gema on his blog.

+0

muy fresco, gracias! – sa125

+0

La versión de gema 0.5.1 es compatible con los rieles 3, pero un simple cambio en gemspec (consulte https://github.com/ivalkeen/validation_scopes/commit/acc1545a028605997e87fd41efece0ddffd3b999) permite su uso en rieles 4. – KenB

1

hice mi propia joya para resolver el problema de los carriles 4.1+: https://github.com/s12chung/active_warnings

class BasicModel 
    include ActiveWarnings 

    attr_accessor :name 
    def initialize(name); @name = name; end 

    warnings do 
    validates :name, absence: true 
    end 
end 

model = BasicModel.new("some_name") 
model.safe? # .invalid? equivalent, but for warnings 
model.warnings # .errors equivalent 
Cuestiones relacionadas