Ruby on Rails: Enable File Downloads Using link_to
In a Ruby on Rails app I was working on, I wanted to include a link that would download a user’s data (bank statements in this case) as JSON.
Originally I had the following ERB:
<%= link_to 'Download All Statements as JSON', statements_download_path %>
Clicking this link would show JSON in the browser, but it wouldn’t download a JSON file, which is what I wanted.
The solution was to add a download attribute to the ERB snippet:
<%= link_to 'Download All Statements as JSON', statements_download_path, download: 'statements.json' %>
Full Setup
For additional context, here is all the code required to get this to work.
First I created this method in statements_controller.rb:
def download
render json: @user.statements
end
Then I added a new route to routes.rb:
get 'statements/download', to: 'statements#download'
And then I added the link_to helper in the view:
<%= link_to 'Download All Statements as JSON', statements_download_path, download: 'statements.json' %>
The link_to ERB helper is creating this HTML:
<a download="statements.json" href="/statements/download">Download All Statements as JSON</a>
The download attribute can be customized in ERB. For example, I can name the file based on the user’s name like so:
<%= link_to 'Download All Statements as JSON', statements_download_path, download: "#{@user.name.downcase}-statements" %>
And it will generate the following HTML:
<a download="nelson-statements" href="/statements/download">Download All Statements as JSON</a>
This link will trigger a download for nelson-statements.json in my case.
Ultimately this was a case of understanding the download HTML attribute for <a> tags and how to use it in Rails.
Further Reading and References
Note that there are other ways of handling this, like using the send_data method in a controller. But that’s beyond the scope of this post. Read more about it here: https://api.rubyonrails.org/v7.0.1/classes/ActionController/DataStreaming.html#method-i-send_data
References: