6

Questo è il mio modello di immagine, in cui ho implementato un metodo per convalidare le dimensioni del fissaggio:immagine Paperclip Dimensioni convalida personalizzata

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 

Questo funziona bene, ma non è riutilizzabile in quanto il metodo assume valori fissato per larghezza & altezza. Voglio trasformarlo in un validatore personalizzato, quindi posso usarlo anche in altri modelli. Ho letto le guide su questo, so che sarà qualcosa di simile in app/modelli/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 

ma so che mi manca qualcosa causa di questo codice non funziona. Il fatto è che voglio chiamare la convalida come questa nel mio modello:

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

Qualche idea su come implementare questo validatore?

+1

Non sono sicuro ma ho pensato di poter accedere alla larghezza e all'altezza tramite l'attributo opzioni .. come: 'opzioni [: larghezza]' e 'opzioni [: altezza]' –

risposta

16

mettere questo in app/validatori/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 

Poi, nel modello:

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

Non è necessario aggiungere il validator to load_path, purché si inserisca il file in models/e lo si chiami seguendo le convenzioni Rails (dimensions_validator.rb). Ho modificato la risposta. Grazie! – Agis

+0

Ho aggiornato la risposta .. –

+0

Grande. Come possiamo eseguire il controllo solo se un'immagine è stata caricata? Ho provato qualcosa a meno che record.nil? e 'salvo valore.nil?' ma non ha funzionato. – Agis