6

Ésta es mi modelo de imagen, en la que he implementado un método para la validación de las dimensiones de la fijación:imagen Paperclip Dimensiones validador personalizado

class Image < ActiveRecord::Base 
    attr_accessible :file 

    belongs_to :imageable, polymorphic: true 

    has_attached_file :file, 
        styles: { thumb: '220x175#', thumb_big: '460x311#' } 

    validates_attachment :file, 
         presence: true, 
         size: { in: 0..600.kilobytes }, 
         content_type: { content_type: 'image/jpeg' } 

    validate :file_dimensions 

    private 

    def file_dimensions(width = 680, height = 540) 
    dimensions = Paperclip::Geometry.from_file(file.queued_for_write[:original].path) 
    unless dimensions.width == width && dimensions.height == height 
     errors.add :file, "Width must be #{width}px and height must be #{height}px" 
    end 
    end 
end 

Esto funciona bien, pero no es reutilizable ya que el método tiene valores fijos para ancho & altura. Quiero transformar esto en un Validador personalizado, así puedo usarlo en otros modelos también. He leído las guías acerca de esto, sé que va a ser algo como esto en app/modelos/dimensions_validator.rb:

class DimensionsValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    dimensions = Paperclip::Geometry.from_file(record.queued_for_write[:original].path) 

    unless dimensions.width == 680 && dimensions.height == 540 
     record.errors[attribute] << "Width must be #{width}px and height must be #{height}px" 
    end 
    end 
end 

pero sé que me falta algo porque el código no funciona. Lo que pasa es que quiero llamar a la validación de esta manera en mi modelo:

validates :attachment, dimensions: { width: 300, height: 200}.

¿Alguna idea de cómo debe implementarse este validador?

+1

No estoy seguro pero pensé que puede acceder a su ancho y alto a través del atributo de opciones .. como: 'options [: width]' and 'options [: height]' –

Respuesta

16

poner esto en app/validadores/dimensions_validator.rb:

class DimensionsValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    # I'm not sure about this: 
    dimensions = Paperclip::Geometry.from_file(value.queued_for_write[:original].path) 
    # But this is what you need to know: 
    width = options[:width] 
    height = options[:height] 

    record.errors[attribute] << "Width must be #{width}px" unless dimensions.width == width 
    record.errors[attribute] << "Height must be #{height}px" unless dimensions.height == height 
    end 
end 

Luego, en el modelo:

validates :file, :dimensions => { :width => 300, :height => 300 } 
+0

No tenemos que agregar el validator para load_path siempre que coloque el archivo en modelos/y asígnele el nombre siguiendo las convenciones de Rails (dimensions_validator.rb). He editado la respuesta. ¡Gracias! – Agis

+0

He actualizado la respuesta. –

+0

Genial. ¿Cómo podríamos realizar el control solo si se carga una imagen? He intentado algo 'a menos que record.nil? ' y 'a menos que value.nil?' pero no funcionó. – Agis

Cuestiones relacionadas