Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validating attachment contents on upload with Paperclip gem

Paperclip has validator methods for validating the presence, size, and content-type of files. But is there a way to validate the contents of the file before the record is saved?

I tried doing validate :my_method and opening the file from [attachment].path in my_method, but of course that fails because the attachment hasn't been moved to its final resting place in the file system before the record is saved.

Writing a custom Paperclip post-processor seemed like an option because it has access to the File object belonging to the attachment before the record is saved, but a failing processor won't invalidate the record before it's saved.

Is there a good way to do this? How else can I make sure that I only have conforming files living in my app? (Are there other callbacks I can use that will gracefully delete the entire record if the file isn't valid?)

edit: Ooh. In particular, will raising ActiveRecord::Rollback from an after_save callback do something sane?

like image 765
Tim Smith Avatar asked Aug 12 '11 18:08

Tim Smith


2 Answers

Ah, but you can access the File object from a validator before the record is saved, by calling [attachment].to_file. Running my parser against [attachment].to_file.path (instead of attachment.path) in my_method seems to work just fine.

Per https://stackoverflow.com/questions/7047183/how-to-set-an-attribute-for-a-model-instance-in-a-paperclip-post-process-callback, [attachment].queued_for_write[:original].path might also be an option.

like image 138
Tim Smith Avatar answered Oct 01 '22 02:10

Tim Smith


Great question, and perhaps someone who has experience with this can give you a better answer, but given that there doesn't appear to be a way to do this within the DSL provided by Paperclip, I would recommend just building your own Paperclip validator (not post-processor).

You can use an existing validator as an example, and drop it into app/lib/paperclip/matchers/validate_foobar.rb (be sure to set your config/application.rb to load from your lib folder) and you're good to go.

like image 20
coreyward Avatar answered Oct 01 '22 03:10

coreyward