5

I have this coupon form

    <%form_for(:download,:download,:url=>{:controller=>"coupons",:action=>"verifycoupon"},:remote=>true) do |f| %>
    <%=text_field :download,:code%>
    <%=f.submit "verify"%>
    <%end%>

and after validating the code on the controller's action i have a confirmation like:

render :update do |page|
    page.alert "OK"
end

Now I want to send a file to the browser with the send_file instruction but nothing seems to happen

send_file("/path/to/my/file.extension")

and in the log I can see

"Sent file /path/to/my/file.extension (0.1ms)"

I was wondering if there's something like

render :update do |page|
   page.send_file("/path/to/my/file.extension")
end

 

#### Update #######

my Controller's action looks something like

def verifycoupon
   code = Code.find(params[:download][:code])
   if code
     if code.is_active?
     render :update do |page|
        page.alert "ok"
     end
       send_file("/path/to/my/file.extension")
     else
       render :update do |page|
          page.alert "this code has already been used"
       end
     end
   else
   render :update do |page|
     page.alert "Code does't exist"
   end
   end
end
Mr_Nizzle
  • 6,644
  • 12
  • 55
  • 85

3 Answers3

7

I have the same problem, well kind of.

In my view I had a link_to tag with remote: true.

The link aimed an action that produced a PDF. The PDF was generated (with prawn and thinreports) and sent, but the download dialog did not popup.

So I remove the remote: true and add a target: '_self', so it ended up like this (I am using haml)

!= link_to image_tag( 'print.png' ) + (I18n.t :buttons)[:comments][:print],
    customer_comment_path(@address_book),
    { target: '_self' }

And it worked just fine.

I did not have to do the "Ajax Request -> Server -> Response -> Redirect -> Client -> request which downloads -> ..." mentioned above.

3

I've heard that the solution is to send a redirect to an end-point where does the send_file back from Ajax.

So, Ajax Request -> Server -> Response -> Redirect -> Client -> request which downloads -> you stay on the same page.

def show
  # if javascript, then redirect to file_sender
end

def file_sender
  # Send file from here.
end

See here http://anaphoral.blogspot.com/2009/03/sendfile-or-senddata-in-linktoremote.html

Aditya Sanghi
  • 13,370
  • 2
  • 44
  • 50
  • Now, how can i protect the `file_sender` action? like under the protected statemen, because if I put the `file_sender` action under the `protected` statement i can't do the `page.redirect_to :action=>"file_sender"` – Mr_Nizzle May 16 '11 at 15:42
  • 1
    Why dont you make it a public facing endpoint but provide the same before_filter authentication/protection you provide to the "show" action? – Aditya Sanghi May 16 '11 at 16:08
1

Where to you call sendfile? I have a controller action like this:

def show
  # ... skipped initalization of requestedfile
  if File.exists?(requestedfile)
    send_file(requestedfile, :type => "application/pdf", :disposition => "inline"
  end
end

Works fine for me.

jhwist
  • 15,201
  • 3
  • 40
  • 47