Send_file Rails3, Ruby 1.9.2

I’m perty new to rails and I have an app where I want to have secure
file downloads, so I can’t just drop the files in public/data, I need
to use send_file. I found the post (pasted at bottom) that explained
how to do this. When I go to implement it, I wanted to try the
simplest thing first, so I have this code:

datafiles_controller.rb:
def download
send_file(‘/file_uploads/Productivity.pdf’, :disposition
=> :attachment)
end
datafiles/index.html.erb
<%=button_to “Download File”, :action=>‘download’%>

when I load index.html it gives the error “No route matches
{:action=>“download”, :controller=>“datafiles”}”
so even though “resources :datafiles” is already in my routes.rb file,
I added: get “datafiles/download”
now the page loads, I click the “Download File” button and it gives me
the error “No route matches “/datafiles/download””

I vaguely remember reading that every def in a controller should
correspond to it’s own erb file, so I created Views/datafiles/
download.erb as a blank page.
But that didn’t make any difference. I’m at a loss as to what I’m
doing wrong, can someone give me some suggestions?

post refered to above:

http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/9ad5649a7601045d/4d748526506abc59?lnk=gst&q=file+download#4d748526506abc59

Is there a way to retrieve a file off the server or hard drive? I
have a program that creates a file and I would like a button to
retrieve the file so the user can save it somewhere. Not ajax right
now.

view

<%=button_to “Download File”, :action=>‘download’%>

controller

def download
send_file(path_to_file, :disposition => :attachment)
end
send_file documentation
http://railsmanual.org/module/ActionController::Streaming/send_file/1

resources :datafiles will create some default routes, but they don’t
include download. You need to add a member route for the download
action.

http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/

Luke

If I comment out everything in my index action in my
datafiles_controller
and paste in:
send_file(’/file_uploads/Productivity.pdf’, :disposition
=> :attachment)
it works, so obviously, the send_file command is good, the
problem is with my routing. What do I need to add to my
routes.rb file so I can create a new download action? or perhaps
even more generally does someone know of a good guide that
explains routing? I thought having “resources :datafiles” in my
routes.rb file was enough and rails would just detect any new
actions automatically.

Are you going to make me do this for you ? :wink:

resources :datafiles do
member do
get :download
end
end

And seriously, read this stuff:
http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/

Luke

excellent, ty

in case someone else has similar problems, the code that I got working
is:

downloading:

controller: datafiles_controller
def download
@datafile = Datafile.find(params[:id])
send_file(’/var/www/pub.website.com/file_uploads/’+
@datafile.name , :disposition => ‘inline’)
end

View: index.html.erb
<% for datafile in @datafiles %>
<%= datafile.name %>
<%= link_to(“Download
File”, :action=>‘download’,:controller=>‘datafiles’,:id=>datafile) %>
<% end %>

routes.rb
resources :datafiles do
member do
get :download
end
end

uploading:

datafiles_controller:
def create
u_id = session[:user_id]
@file = params[:upload]
post = Datafile.save(params[:upload],u_id)
if post
post = Datafile.event(u_id,“Uploaded”,“File”,
@file[‘datafile’].original_filename)
flash[:notice] = ‘File has been uploaded successfully.’
redirect_to :action => ‘new’
else
flash[:notice] = ‘File was not uploaded (invalid data).’
redirect_to :action => ‘new’
end
end

datafiles view: new.html.erb
<% form_tag( { :action => ‘create’ }, :multipart => true ) do %>
<% flash.each do |key, value| %>
<%=value%>
<% end %>

Select File:

<%= file_field ‘upload’, ‘datafile’ %>
<%= submit_tag “Upload” %>
<% end %>

datafiles view: index.html.erb
<% for datafile in @datafiles %>



<%= datafile.name %>
<%= link_to(“Download
File”, :action=>‘download’,:controller=>‘datafiles’,:id=>datafile) %>

<% @user = User.find(datafile.user_id) %>
<%= @user.full_name %>
<%= datafile.created_at.strftime("%m/%d/%Y at %I:
%M%p") %>

<% end %>