Smarter paperclip validations

model, paperclip, ruby-on-rails, validation

Solution

validates_attachment_size :photo, :less_than => 1.megabyte, 
  :unless => Proc.new { |imports| imports.photo_file_name.blank? }

Problem

I'm using paperclip in a rails app and have the following three validations in my model ``` validates_attachment_presence :photo validates_attachment_size :photo, :less_than=>1.megabyte validates_attachment_content_type :photo, :content_type=>['image/jpeg', 'image/png', 'image/gif'] ``` If the user forgets to add an attachment, all three validations fail and thus, the user is presented with the following three errors: ``` # Photo file name must be set. # Photo file size file size must be between 0 and 1048576 bytes. # Photo content type is not included in the list ``` I think it would be best to just show the first error in this instance since the other two errors are purely consequential... I would prefer the user to only ever see the second two errors if an attachment has been added but doesn't meet the validation criteria. I'm certain there is no pre-baked validation that does this sort of thing and from reading the code in vendor/plugins/paperclip/lib/paperclip.rb I see that the validates_attachment_size method supports the :unless parameter as shown: ``` def validates_attachment_presence name, options = {} message = options[:message] || "must be set." validates_presence_of :"#{name}_file_name", :message => message, :if => options[:if], :unless => options[:unless] end ``` So, I was thinking that I could do something like the following: ``` validates_attachment_size :photo, :less_than=>1.megabyte, :unless=> :photo.blank ``` But that breaks the app. Anyone have any experience of doing this sort of thing? Would be a nice contribution to the paperclip source code. EDIT: I've tried using this: ``` validates_attachment_size :photo, :less_than=>1.megabyte, :unless=> Proc.new { |image| image[:photo].nil? } ``` It doesn't quite work though as I've just managed to upload a 5mb mp3 with this validation in place. But it's promising as the error message doesn't appear when the user has not attached a photo.

Original source