Topic: File Upload: No Method Error

I'm trying to write a simple file upload and can't seem to find why I'm getting this error:

NoMethodError in Project filesController#create
undefined method `[]' for #<File:/tmp/CGI4061.0>

Here's my controller:

def create
  @project_file =[:project_file])
    flash[:notice] = 'ProjectFile was successfully created.'
    redirect_to :action => 'new'
    flash[:notice] = "Ah Crap!"
    render :action => 'new'

Here's my model:

class ProjectFile < ActiveRecord::Base
  belongs_to :user
  belongs_to :project

  validates_presence_of :file_name, :content_type, :user_id, :project_id

  def content_type=(project_file)
    write_attribute(:content_type, project_file[:file_name].content_type)
  def file_name=(project_file)
    path = "/project_files/"
    filename = project_file[:project_id].to_s + "_" + project_file[:file_name].original_filename.to_s + filename, "w") { |f| f.write(project_file[:file_name].read) }
    write_attributes(:file_name, filename)

  def file_name
    "/project_files/" + read_attribute(:file_name)

Here's My view (I've inserted the partial for the sake of space and readability):

<h1 class='heading'>Add File</h1>

<%= start_form_tag( {:controller => 'project_files', :action => 'create'}, :multipart => true )%>

<%= file_field 'project_file', 'file_name'  %>
<%= hidden_field 'project_file', 'project_id', :value => params[:project_id] %>
<%= submit_tag 'Upload' %>
<%= end_form_tag %>

If art interprets our dreams, the computer executes them in the guise of programs.

-SICP (Abelson, Sussman)

Re: File Upload: No Method Error

How/Why are you treating project_file as an array within your model? Rails is complaining that the object doesn't provide a '[]' method, presumably where you are trying to call




Unless this is a way of accessing the member variables of the object (I'm quite new to Ruby), it doesn't seem right.


Re: File Upload: No Method Error

From the examples of rewriting accessor and write functions i've seen, that's a totally valid thing to do.  I believe when is called and given params[:project_file] it passes the hash contained by params[:project_file] in via the argument set in the write file_name= function.  However, I could be way off base.  But sadly, and obviously, no one has let me know that I'm writing this all wrong yet.  Thanks for the post, maybe I'll get some more input now.

If art interprets our dreams, the computer executes them in the guise of programs.

-SICP (Abelson, Sussman)

Re: File Upload: No Method Error

From the looks of the error message, the argument passed to file_name=() or content_type=() is a File object. Sounds like a perfect job for a breakpoint. If you haven't used breakpoints before, I would highly recommend trying it out. They make debugging so much easier.

Just add a line "breakpoint" to the beginning of the file_name=() and content_type=() method definitions. Call "script/breakpointer" in the command line (ignore the error message about no breakpoint service found). Now load the page in the web browser that calls the code with the breakpoint in it. When the breakpoint line is called, the script/breakpointer prompt turns into an interactive ruby session right where the breakpoint line was. You have access to all of the local variables and such. You can call "project_file.class" to see what type of object the project_file is. See the docs for some more details. Also see the wiki page.

Railscasts - Free Ruby on Rails Screencasts