ROR newb with MVC question

I’m new to ROR and still trying to wrap my mind around the MVC
construct.
Hope someone can spot what is probably a simple error here.

I need to have a user upload a CSV file, parse the header (the table
field
names) then each row of data, and import the data into its respective
tables.

In the view I have:

<% form_tag ({:action => ‘uploadFile’}, :multipart => true) do %>

Select File : <%= file_field 'upload', 'datafile' %>

<%= submit_tag "Upload" %> <% end %>

in the controller:

class UploadController < ApplicationController

def index
render :file => ‘app\views\upload\uploadfile.html.erb’
end

def uploadFile

post = Import.proc_csv( params[:upload])
flash[:notice] = "File imported successfully"
redirect_to :action => :index

rescue

  flash[:error] = "Error importing file"
  redirect_to :action => 'index'

end

end

and in the model:

class Import < ActiveRecord::Base

require ‘fastercsv’

def self.proc_csv(upload)
row_count = 0
FasterCSV.foreach([:csv_import][:file], :headers => :first_row) do
|row|

  @gr =

Genotype_runs.create(:genotype_date_1=>row[4],:genotype_date_2=>row[5],:genotype_date_3=>row[6])
# use the id of the Genotype_runs record to link to Genotype_data
rec.
Genotype_data.create(:genotype_run_id=> gr.id, :box=>row[0],
:subjectid=>row[1], :labid=>row[2], :well=>row[4],
:created_at=>Time.now,:updated_at=>Time.now)
# print message showing import
$stderr.print “\r%5d …” % csv.lineno
$stderr.flush
row_count = row_count + 1
end
end

def self.save(upload)
name = upload[‘datafile’].original_filename
directory = “public/data/import”
# create the file path
path = File.join(directory, name)
# write the file
File.open(path, “wb”) { |f| f.write(upload[‘datafile’].read) }
end
end

The file upload screen allows me to upload a file, but when I submit it,
I
get the following error:

Errno::ENOENT in UploadController#index

No such file or directory - app\views\upload\uploadfile.html.erb

Which is rather a puzzle for me…any suggestions/insights/comments
appreciated!

–Rick

The most obvious answer is: do you have a file
app\views\upload\uploadfile.html.erb? (also, why the backslashes?)

Not quite sure why you’re rendering a file like that…the idiomatic way
is to have a file in app/views/uploads/index.html.erb that displays
whatever you want (in this case presumably some form of the CSV data).
Rails assumes this and will render index.html.erb without any explicit
rendering.

Garrett L.

Thanks for catching my dumb error with the backslashes…(this is
running on
Linux after all…). As you can tell, I’m crudely cutting-&-pasting code
from online examples…

Yes, there is a file app/views/upload/uploadfile.html.erb, which is the
view
for my Upload class.

I’m not sure why I’m rendering the file like that either – it was just
in
an example I was trying to adapt to my purposes – but I do know if I
take
it out, the form doesn’t work anymore.
All I’m trying to do is have the Submit button feed the selected file to
the
controller correctly, and then to the model correctly, where the data
gets
imported into the database.
But I obviously still have major errors in how this is coded…

Any other suggestions appreciated…

Thanks again,
rixter

So, I commented out the index method in my controller, just leaving the
view
as before.

Now I get the error:
Unknown action

No action responded to index

so my question now is, why doesn’t the method uploadFile get called in
the
controller from the view with this code:

<% form_tag ({:action => ‘uploadFile’}, :multipart => true) do %>

Select File : <%= file_field 'upload', 'datafile' %>

<%= submit_tag "Upload" %> <% end %>

Still a mystery to me…

–rixter

It appears the uploadFile method is getting called because its
redirecting to :index, which doesn’t exist now since you deleted it.

There are many issues here, but try the following:

  1. put the code in uploadfile.html.erb in
    app/views/upload/index.html.erb
  2. uncomment the index action, but make it empty

Garrett L.

OK, I must first inform you, I’m no rails guru (not yet anyways) but
here is
what I think should be your directory structure:

app/
controllers/
uploads_controller.rb # This will contain the
UploadController class
views/
uploads/
index.html.erb # This will be the view to list the
uploaded files (info)
new.html.erb # This will be the form used to
upload
files
models/
upload.rb # This is your model to represent an upload

Now that we have that in place, now the controller index method would
automatically render the index.html.erb so there is no need for you to
render the template directly. If you would like to see the list of
uploaded
document then may be you might need to the following your index
controller
method;

def index
@uploads = Upload.all # this gets all upload information and makes it
available for the view
end

and then you render then in your view, i.e. the index.html.erb file do
the
following to list them all

    <%= @uploads.each do |upload| %>
  • <%= upload.title %>
  • <% end %>

So gives you list of upload info on the index.html.erb page. Now the
next
thing would be to actually create upload info; that where the new action
(a
controller method), and new.html.erb come in. A word of caution here; I
have
never done a form that uploads files so I can not give you much detail
here,
but there is a good gem called paperclip so you might want to check
that
out for details but here is what I would given the information you
provided
above.

In your controller you need to add the following action:

def new
@upload = Upload.new # This is a new upload model that you can use to
create your upload form
end

then in you new.html.erb you add the following:

<% form_for(@upload) do |f| %>

Select File : <%= file_field 'upload', 'datafile' %>

<%= submit_tag "Upload" %> <% end %>

I kinda feel this is a bit incomplete but I’m sure someone can build on
this
or just find another way to help you with your problem. I hope this
helped
in making things clearer. If you are in need of a good place to start
with
RoR go here, railstutorial.org. I can say it is the best and most
complete
book I’ve ever read on programming. It’s that good!

Regards,
Tsega

Ok, I did the following:

  • moved the code to app/views/upload/index.html.erb
  • uncommented the index method in the controller, but made it empty

Now, I no longer get any error message, but when I submit a file and
click
the Upload button, the form just flashes, but comes back with an empty
field
for the input file.
So the desired method, uploadFile, is still not getting called in the
controller.
Here’s what the log says:

Processing UploadController#index (for 127.0.0.1 at [blah,blah,blah]…
Parameters: {“action”=>“index”, “controller”=>“upload”}
Rendering upload/index

I’m still puzzled: why is the uploadFile method not getting called,
when
the submit action clearly states:

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

thx for the help,
still wondering,
rixter

Awesome…thanks Tsega…will chew on this awhile…a big help!

–rixter

One thing I forgot here is that you need to add the create action in
your
controller that would be used to house the code for uploading the file:

def create
post = Import.proc_csv( params[:upload])
flash[:notice] = “File imported successfully”
redirect_to :action => :index
rescue
flash[:error] = “Error importing file”
redirect_to :action => ‘index’
end

To test if the method is actually getting called place raise ‘Inside
uploadFile’ at the top of the method.