19

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.

stephenmurdoch
  • 34,024
  • 29
  • 114
  • 189
  • Which version of paperclip are you using? I've got 2.3.1.1 and what you are describing happens automatically for me. If no file is attached, it only returns that error. If I attach a file, but the size and content type validations fail, it then shows those errors. – Peter Brown Feb 13 '10 at 19:41
  • strange because I'm on 2.3.1.1 of the plugin too... i'm going to go with the suggestion below about creating my own custom error messages anyway because I really don't like the way they tell you the attacment needs to be between 0 and X bytes.... – stephenmurdoch Feb 14 '10 at 00:26
  • I'm using 2.3.2 with same problem – Ben Orozco May 22 '10 at 00:31

2 Answers2

30
validates_attachment_size :photo, :less_than => 1.megabyte, 
  :unless => Proc.new { |imports| imports.photo_file_name.blank? }
shybovycha
  • 11,556
  • 6
  • 52
  • 82
Leonardo Meira
  • 324
  • 2
  • 3
  • 1
    Better than that: :if => Proc.new { |imports| !imports.photo.file? } – Brendon Muir Feb 04 '11 at 00:01
  • I don't know what version this answer was given on but it isn't working on my local system (running Paperclip 2.3.11 on Rails 3.1.3). – pcg79 Feb 23 '12 at 17:41
5

I think you can do it other way. Don't mess with validations. You probably have something like this in your form:

<%= f.error_messages %>

You can remove it and write your own helper to display error messages. Errors are stored in hash:

@photo.errors

Or if you want to get to them through form builder:

f.object.errors
klew
  • 14,837
  • 7
  • 47
  • 59