file upload gives filename as String, no IO object

Hi list,

I'm having a headache with file upload in rails..

In short, the problem boils down to the upload form giving me a String
containing the file name of the uploaded file instead of the IO object
it should give me to access the file's content and MIME type.

I have checked http://railsforum.com/viewtopic.php?id=4642&p=1 and
http://manuals.rubyonrails.com/read/chapter/77, but the problem seems
not to occur there... I also have spent quite some time searching
google and this list on this issue, but nothing that succeeded to
enlighten me came up..

I'm using rails v. 1.2.1.

I have a view with a file upload form:

<% form_tag :action => 'create', :multipart => true do %>
  <%= file_field('photo', 'uploaded_file') %>
  <%= submit_tag "Create" %>
<% end %>

Which renders to

<form action="/photos/create?multipart=true" method="post">
  <input id="photo_uploaded_file" name="photo[uploaded_file]"
size="30" type="file" />
  <input name="commit" type="submit" value="Create" />
</form>

The database model has no column named 'uploaded_file' because this
value is to be split into a field for the MIME and one for the
content. So I added a setter method:

class Photo < ActiveRecord::Base
  def uploaded_file=(file)
    self.mime = file.content_type # => Raises undefined method
`content_type' for "Photo.jpg":String
  end
end

The request parameters from rails' traceback are:

Parameters: {"photo"=>{"creator"=>"Siemen",
"uploaded_file"=>"Photo.jpg"}, "multipart"=>"true",
"commit"=>"Create"}

So also a string here...

Any help would be greatly appreciated!

Siemen

Hi,

I'm having a headache with file upload in rails..

In short, the problem boils down to the upload form giving me a String
containing the file name of the uploaded file instead of the IO object
it should give me to access the file's content and MIME type.
  

did you set tour form to send multipart encoding? If not, that's the problem

regards,

javier ramírez

Hi list,

I'm having a headache with file upload in rails..

In short, the problem boils down to the upload form giving me a String
containing the file name of the uploaded file instead of the IO object
it should give me to access the file's content and MIME type.

I have checked http://railsforum.com/viewtopic.php?id=4642&p=1 and
http://manuals.rubyonrails.com/read/chapter/77, but the problem seems
not to occur there... I also have spent quite some time searching
google and this list on this issue, but nothing that succeeded to
enlighten me came up..

I'm using rails v. 1.2.1.

I have a view with a file upload form:

<% form_tag :action => 'create', :multipart => true do %>
  <%= file_field('photo', 'uploaded_file') %>
  <%= submit_tag "Create" %>
<% end %>

Try this:
<% form_tag({:action => 'create'}, :multipart => true) do %>

The multipart option is not part of the url_for options so you have to make them explicitly separate.

Which renders to

<form action="/photos/create?multipart=true" method="post">
  <input id="photo_uploaded_file" name="photo[uploaded_file]"
size="30" type="file" />
  <input name="commit" type="submit" value="Create" />
</form>

The database model has no column named 'uploaded_file' because this
value is to be split into a field for the MIME and one for the
content. So I added a setter method:

class Photo < ActiveRecord::Base
  def uploaded_file=(file)
    self.mime = file.content_type # => Raises undefined method
`content_type' for "Photo.jpg":String
  end
end

The request parameters from rails' traceback are:

Parameters: {"photo"=>{"creator"=>"Siemen",
"uploaded_file"=>"Photo.jpg"}, "multipart"=>"true",
"commit"=>"Create"}

So also a string here...

Any help would be greatly appreciated!

Siemen

In your controller, you probably want something like:

   def create
     data = params[:photo].delete('uploaded_file') # HashWithIndifferentAccess still needs the actual key type to .delete

     @photo = Photo.new(params[:photo])

     if data.blank?
       flash[:error] = "No image file selected for upload"
       redirect_to :action => 'new' and return
     end
     content = data.read
     if content.blank?
       flash[:error] = "Selected upload file was empty"
       redirect_to :action => 'new' and return
     end
     # you can then do stuff with the content or with:
     # filename = data.original_filename
     # content_type = data.content_type

     # eventually,
     if @photo.save
     # OK
     else
     # too bad
     end
   end

I might have missed something that you want to do, but this ought to at least get you started.

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

did you set tour form to send multipart encoding? If not, that's the problem

I thought sI had

<% form_tag :action => 'create', :multipart => true do %>

However, this results in the multipart=true-thing being included in
the url, not as an attribute of the form tag:

<form action="/photos/create?multipart=true" method="post">

Using more explicit () and {} solved it:

<% form_tag({:action => 'create'}, {:multipart => true}) do %>

gives me the correct form:

<form action="/photos/create" enctype="multipart/form-data"
method="post">

Thank you very much for the helpful answer!

Siemen

Yes, definitely. Thanks!

- Siemen