martedì 14 dicembre 2010

How to send a dinamically generated file in a Rails 3 application

Sometimes can be useful to send a file to the user instead of rendering a page. When you have a fixed location for the file you simply achieve this with a link to the file inside the view, but there may be some cases in wich you have to dinamically generate the file to send. To do this you have to add a new custom action to the controller in wich you want to add the download.
In this example I suppose to have a simple blog application where the user can download the content of a post in text format. So, in the posts controller we add the following action:
class PostsController < ApplicationController

...

def download
  @post = Post.find(params[:id])
  send_data @post.body, :filename => @post.title
end

...

end
After this we have to add a new line into our config/routes.rb file to make this action accessible with a get request:
...
resources :posts do
  member do
    get 'download'
  end
end
...
Now we can add a simple link in our view:
<%= link_to 'Download', download_post_path(@post), :title => 'Download post' %>
Here we suppose to have the instance variable @post created somewhere (i.e. in the show action).
Now we can display our page and download the post as a text file.
Hope this helps, have fun with Ruby on Rails!