Search code examples
ruby-on-railspaperclippaperclip-validation

Paperclip validation of StringIO not valid


I would like to use the Paperclip gem (4.3.6) to stream a file from a 3rd party API and use the body of the HTTP response as an attachment on an ActiveRecord model representing a Fax.

class Fax
  has_attached_file :fax_document
  validates_attachment_content_type :fax_document, content_type: { content_type: ["application/pdf", "application/octet-stream"] }
end

I am using the code below to get the HTTP response from the API server and save it as an attachment on the Fax model. (Code below is modified slightly for brevity).

#get the HTTP response body
response = download(url)

#add the necessary attributes to the StringIO class. This technique is demonstrated in multiple SO posts.
file = StringIO.new(response)
file.class.class_eval { attr_accessor :original_filename, :content_type }
file.original_filename = "fax.pdf"
file.content_type = 'application/pdf'

#save the attachment
fax = Fax.new
fax.fax_document = file
fax.save

The response variable contains what looks like a string representation of a pdf binary object and fax.save raises a content_type not valid error. If I explicitly relax the Paperclip validation on the fax model using do_not_validate_attachment_file_type :fax_document, then the attachment will save properly.

I suspect that Paperclip content type validation is failing because it can't tell that that the content returned from is in fact 'application/pdf'.

Why is Paperclip raising a content_type not valid error? How do I tell Paperclip that the body of the response is a pdf?


Solution

  • I think that your validates_attachment_content_type definition is wrong. You should not pass a hash to the :content_type option but a single content type or an array of types.

    In your case, the following should do it:

    validates_attachment_content_type :fax_document, 
           content_type: ["application/pdf", "application/octet-stream"]