2009-12-22 22 views
21

Primero, déjenme decir que soy extremadamente nuevo en Rails (jugué con eso una o dos veces pero me obligué a escribir un proyecto completo con él ahora, comencé ayer).Validar una propiedad de modelo es mayor que otra

Estoy tratando de validar que una propiedad de modelo (¿terminología?) Es mayor que otra. Esto parece ser una instancia perfecta para validates_numericality_of con la opción greater_than, pero lamentablemente eso arroja un error al decirme greater_than expects a number, not a symbol. Si intento encasillar ese símbolo .to_f obtengo un error de undefined method.

Esto es lo que finalmente hice y tengo curiosidad sobre si hay una mejor manera. Es solo un sistema simple para controlar los lanzamientos de proyectos, solo tenemos lanzamientos mayores/menores (un punto) por lo que flotar se sintió como la decisión correcta aquí.

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release 
    validates_numericality_of :next_release 
    validate :next_release_is_greater 

    def next_release_is_greater 
     errors.add_to_base("Next release must be greater than current release") unless next_release.to_f > current_release.to_f 
    end 
end 

Esto funciona - pasa la prueba de la unidad correspondiente (a continuación para su placer de la vista), sólo soy curioso en cuanto a si hay una manera más fácil - algo que podría haber tratado de otra manera.

de los ensayos correspondientes unidad:

# Fixture data: 
# PALS: 
#  name: PALS 
#  description: This is the PALS project 
#  current_release: 1.0 
#  next_release: 2.0 
#  project_category: 1 
#  user: 1 
def test_release_is_future 
    project = Project.first(:conditions => {:name => 'PALS'}) 
    project.current_release = 10.0 
    assert !project.save 

    project.current_release = 1.0 
    assert project.save 
end 

Respuesta

19

Como habrás notado, la única forma es usar un validador personalizado. La opción: greater_than debe ser un número entero. El siguiente código no funcionará porque la versión actual y la siguiente están disponibles solo a nivel de instancia.

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release 
    validates_numericality_of :next_release, :greater_than => :current_release 
end 

El propósito de la opción greater_than es para validar el valor contra una constante estática o un otro método de clase.

Por lo tanto, no importa y siga adelante con su validador personalizado. :)

+0

excelente respuesta, respuesta detallada - justo lo que necesitaba (además de un poco de tranquilidad). –

+0

Gran respuesta, corrige el error de ortografía cuando tienes la oportunidad de "greather_than". Gracias de nuevo. – ghayes

+0

Hecho, gracias. –

0

Esa es la mejor manera de ejecutar una validación personalizada, sin embargo, es posible que desee ver en algo así como factory_girl como un reemplazo para los accesorios (que parece que se está utilizando):

http://github.com/thoughtbot/factory_girl

Su prueba de la unidad sería el siguiente aspecto:

def test_... 
    Factory.create(:project, :current_release => 10.0) 
    assert !Factory.build(:project, :current_release => 1.0).valid? 
end 
4

Con Rails 3.2, puede validar dos campos uno contra el otro sobre la marcha al pasar en un proceso.

validates_numericality_of :next_release, :greater_than => Proc.new {|project| project.current_release } 
6

validates_numericality_of acepta a large list of options y algunos de ellos pueden ser suministrados con un proc o un símbolo (esto significa, básicamente, se puede pasar un atributo o un método completo).

para validar la numericality de una propiedad es mayor que otro valor:

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release, less_than: ->(project) { project.next_release } 

    validates_numericality_of :next_release, 
    greater_than: Proc.new { project.current_release } 
end 

Para aclarar, ninguna de estas opciones puede aceptar un proc o símbolo:

  • :greater_than
  • :greater_than_or_equal_to
  • :equal_to :less_than
  • :less_than_or_equal_to

docs validates_numericality:http://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html#method-i-validates_numericality_of

utilizando procs con validaciones: http://guides.rubyonrails.org/active_record_validations.html#using-a-proc-with-if-and-unless

Cuestiones relacionadas