views:

33

answers:

1

Could someone enlighten me on how to upload files the RESTful way to a Rails application?

I experimented with curl to simulate uploading an image to a rails controller. At first I got authenticity token errors and so disabled them, and then tried

curl -F "[email protected]" http://localhost:3000/photos/create

but this didn't work, and I get the error that "you can only upload photos".

I am assuming this has something to do with setting the content-type of the file uploaded, but I'm not sure how to do this.

I'm using this code in my controller (taken from the Agile Rails book)

class Photo < ActiveRecord::Base
  belongs_to :user

  validates_format_of :content_type, :with => /^image/,
     :message => "--- you can only upload pictures"

  def uploaded_picture=(picture_field)
    self.name = base_part_of(picture_field.original_filename)
    self.content_type = picture_field.content_type.chomp
    self.data = picture_field.read
  end

  def base_part_of(file_name)
    File.basename(file_name).gsub(/[^\w._-]/, '')
  end
end

Using a web browser works great, with this view code:

<% form_for(@photo_reflection, :html => { :multipart => true } ) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :user_id %><br />
    <%= f.text_field :user_id %>
  </p>
  <p>
    <%= f.label :data %><br />
    <%= f.file_field("uploaded_picture") %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

It would be great if someone could tell me how to upload files the RESTful way without bypassing the authenticity tokens.

+2  A: 

Per curl's manpage, you can set the file type like so:

curl -F "[email protected];type=image/gif" http://localhost:3000/photos/create

In order to handle the authenticity token, you would have to use curl to GET the resource including the form, then construct the POST request using the token provided in response to the GET request.

Jeremy W. Sherman
I got it to work with curl -F "photo[uploaded_picture][email protected];type=image/gif" http://localhost:3000/photos/create
JC