Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support uploading files from multipart forms in Rails #615

Closed
kimroen opened this issue Dec 14, 2017 · 4 comments
Closed

Support uploading files from multipart forms in Rails #615

kimroen opened this issue Dec 14, 2017 · 4 comments

Comments

@kimroen
Copy link

kimroen commented Dec 14, 2017

Hi! Recently, our form to upload verification documents to Stripe stopped working.

We do something that can be boiled down to this:

In the template:

<%= form_for :identity_verification do |f| %>
  <%= f.label :image, "Your identification" %>
  <%= f.file_field :image %>
<% end %>

In the controller

def create
  image = params[:identity_verification][:image]
  Stripe::FileUpload.create({
    purpose: 'identity_document',
    file: image
  })
end

After some digging, we realized that this started failing because Rails represents the uploaded file as an instance of ActionDispatch::Http::UploadedFile, and that Stripe now doesn't handle getting one of these passed in any more after switching from rest-client to Faraday.

Luckily in 1.8.1 the stripe gem introduced support for passing in a Tempfile, and you can get one of those out of the ActionDispatch::Http::UploadedFile instance by calling tempfile on it, so this fixed it for us:

 def create
   image = params[:identity_verification][:image]
   Stripe::FileUpload.create({
     purpose: 'identity_document',
-    file: image
+    file: image.tempfile
   })
 end

I understand the intention here is to not break the old behavior, so I just wanted to both let you know about this and document the fix so other people don't have to go spelunking like we did 👍

@kimroen
Copy link
Author

kimroen commented Dec 14, 2017

In the interest of sharing, I thought it could be worth mentioning that rest-client determines if something is a file by checking that it responds to both path and read:

https://github.com/rest-client/rest-client/blob/f450a0f086f1cd1049abbef2a2c66166a1a9ba71/lib/restclient/payload.rb#L55

If you wanted to maintain the same API you could do the same thing. File, Tempfile and ActionDispatch::Http::UploadedFile all respond to both of these methods, so that would cover the things we know about so far, and might be better than checking is_a? with everything that could behave like a file.

@ob-stripe
Copy link
Contributor

Hi @kimroen, thanks for the report! We recently reintroduced support for uploading Tempfiles in stripe-ruby v3.8.1, so you should be able to do:

  Stripe::FileUpload.create({
    purpose: 'identity_document',
    file: image.tempfile
  })

using the latest stripe-ruby.

That said, your proposal of mimicking rest-client's behavior makes a lot of sense! I'll run some tests and push a patch unless I run into any surprises.

@brandur-stripe
Copy link
Contributor

We've released @ob-stripe's patch in 3.9.1.

@kimroen
Copy link
Author

kimroen commented Dec 15, 2017

Perfect, thank you both ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants