Friday, 5 December 2008

Posting a file with ActiveResource

« Relay mail via Google SMTP or AuthSMTP with Postfix | Main | Geokit geocoding with multiple matches »

Recently I had to put or post files to a web service using ActiveResource. I thought that it was a common tasks but, after searching a bit, I wasn't able to find any documentation about how to do that and so I ended up implementing my dirty solution.

Luckily, Rails already knows how to parse a file parameter so I only had to produce an XML conforming to what that parameter parser expects. If you, like me, are receiving the file from a multipart/form-data form in a Rails application, then you have an UploadedStringIO instance to play with:

module ActionController
  class UploadedStringIO
    def to_xml(options = {})
      options[:indent] ||= 2
      xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
      xml.instruct! unless options[:skip_instruct]
      dasherize = !options.has_key?(:dasherize) || options[:dasherize]
      _root = options[:root] || 'file'
      root_tag = dasherize ? _root.to_s.dasherize : _root.to_s
      xml.tag!(root_tag, ActiveSupport::Base64.encode64(string), :type => 'file', :name => original_path, 
        (dasherize ? 'content-type' : 'content_type') => content_type)
    end
  end
end

With that, if you have a Tournament model, with a flier attribute and you assign to it a text file (file name: flier.txt, file content: abc) then ActiveResource will post/put something like:

<?xml version="1.0" encoding="UTF-8"?>
<tournament>
  <flier type="file" name="flier.txt" content-type="text/plain">YWJj
</flier>
</tournament>

that is what Rails wants.

Technorati Tags:

Posted by Nicola Piccinini at 6:03 PM CET in devel/