This project is archived and is in readonly mode.
[patch] ActiveResource doesn't support file uploads/attachments
Reported by Nick M | February 9th, 2011 @ 05:26 AM
Problem
ActiveResource doesn't currently support file objects within an instance. If you try and save an ActiveResource instance that contains a file attachment, the file object's attributes get serialized, but not the file itself. For example, this is what ActiveResource currently sends when trying to create a new object that contains an uploaded file:
<user>
<first-name>Tom</first-name>
<last-name>Jones</last-name>
<address>1234 Test Rd</address>
<avatar type="yaml">--- !ruby/object:ActionDispatch::Http::UploadedFile
content_type: image/png
headers: |
Content-Disposition: form-data; name="user[avatar]"; filename="Picture 4.png"
Content-Type: image/png
original_filename: Picture 4.png
tempfile: !ruby/object:File {}
</avatar>
</user>
That serialized <avatar>
content obviously
won't work on the remote server since it doesn't actually contain
the file data. You can try to base64 encode your file content
inside the XML or JSON data being sent to the remote server, but
that is cumbersome, slow, and requires individual changes to both
your client and server code.
Patch
I've attached a patch with tests (for both master and the
3-0-stable branch) that gives you the option to send and encode
your ActiveResource POST and PUT request data as
application/x-www-form-urlencoded
or, when file
attachments are present, multipart/form-data
. Since
Net::HTTP doesn't natively handle mutlipart attachments, I
introduced a dependency on the Payload
class from
rest-client.
To enable this new encoding option, I added a new class
attribute, ActiveRecord::Base.payload_encoding
. It
works similar to how the format
option works (it can
be set globally or on a per-class basis).
payload_encoding
defaults to :serialized
for compatibility (data will continue to be posted as serialized
JSON or XML). Or payload_encoding
can be set to
:form
to encode the attributes as form
elements/multipart data for attachments.
This feature also seems handy to have for remote web services that expect data encoded this way (and not as JSON or XML).
Finally, regarding compatibility, it's disabled by default so it shouldn't interfere, but if you're targeting a Rails-based backend service, I believe enabling it should be mostly seamless. Since a Rails backend will automatically decode the XML and JSON data sent to into form parameters anyway, this simply negates the need for that step.
Example
class Image < ActiveResource::Base
self.site = "http://localhost:3001/"
self.format = :json
self.payload_encoding = :form
end
Image.find
and others will continue to fetch the
data using JSON. However, Image.create
and other save
methods will post the data as form attributes, allowing multipart
attachments to also work.
No comments found
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>