Permalink
Browse files

first stab at the section on file uploads

  • Loading branch information...
1 parent 68ddc72 commit d99fa392dd2616c24d357c192d7525a61e2d2e05 @fcheung fcheung committed Jan 1, 2009
Showing with 34 additions and 0 deletions.
  1. +34 −0 railties/doc/guides/source/form_helpers.txt
@@ -581,6 +581,40 @@ which produces the following output:
</form>
-------------
+File Uploads
+--------------
+A common task is uploaded some sort of file, whether it's a picture of a person or a CSV file containing data to process. The most important thing to remember with file uploads is that the form's encoding *MUST* be set to multipart/form-data. If you forget to do this the file will not be uploaded. This can be done by passing `:multi_part => true` as an HTML option. This means that in the case of `form_tag` it must be passed in the second options hash and in the case of `form_for` inside the `:html` hash.
+
+The following two forms both upload a file.
+-----------
+<% form_tag({:action => :upload}, :multipart => true) do %>
+ <%= file_field_tag 'picture' %>
+<% end %>
+
+<% form_for @person, :html => {:multipart => true} do |f| %>
+ <%= f.file_field :picture %>
+<% end %>
+-----------
+Rails provides the usual pair of helpers: the barebones `file_field_tag` and the model oriented `file_field`. The only difference with other helpers is that you cannot set a default value for file inputs as this would have no meaning. As you would expect in the first case the uploaded file is in `params[:picture]` and in the second case in `params[:person][:picture]`.
+
+What gets uploaded
+~~~~~~~~~~~~~~~~~~
+The object in the params hash is an instance of a subclass of IO. Depending on the size of the uploaded file it may in fact be a StringIO or an instance of File backed by a temporary file. In both cases the object will have an `original_filename` attribute containing the name the file had on the user's computer and a `content_type` attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in `#\{RAILS_ROOT\}/public/uploads` under the same name as the original file (assuming the form was the one in the previous example).
+
+-----------------
+def upload
+ uploaded_io = params[:person][:picture]
+ File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'w') do |file|
+ file.write(uploaded_io.read)
+ end
+end
+----------------
+
+Once a file has been uploaded there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several plugins designed to assist with these. Two of the better known ones are http://github.com/technoweenie/attachment_fu[Attachment-Fu] and http://www.thoughtbot.com/projects/paperclip[Paperclip].
+
+Dealing with Ajax
+~~~~~~~~~~~~~~~~~
+Unlike other forms making an asynchronous file upload form is not as simple as replacing `form_for` with `remote_form_for`. With an AJAX form the serialization is done by javascript running inside the browser and since javascript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.
Parameter Names
---------------

0 comments on commit d99fa39

Please sign in to comment.