send_data
sets the whole server response, so the browser is just receiving a CSV file, not a web page. This is why your flash message is not displaying. An alternative could be to generate a temporary CSV file (with random name) and provide back a link to it:
def export_csv
if params[:from_date].present? && params[:to_date].present?
@users = User.where("created_at between ? and ?", params[:from_date], params[:to_date])
if !@users.blank?
#Create temporary CSV report file and get the path to it.
csv_file_path = create_csv_file(User.to_excel(@users))
#Change the flash message a bit for requesting the user
#to click on a link to download the file.
flash.now[:success] = "Your report has been successfully generated! Click <a href='#{csv_file_path}'>here</a> to download".html_safe
else
flash.now[:notice] = "No records over selected duration!"
end
else
flash.now[:notice] = "Select from and to date.."
end
end
Of course you should implement the function create_csv_file
. To avoid keeping old files in your server, you could implement a new method, say download_report
which would read the file, send back to the client with send_data
and finally delete it.
EDIT
Pseudocode for the functions mentioned above:
require 'tempfile'
def create_csv_file(data)
#Create a temporary file. If you omit the second argument of Tempfile.new
#then the OS's temp directory will be used.
tmp = Tempfile.new('report', 'my/temp/dir')
tmp.write(data)
tmp.close
return tmp.path
end
#Method in controller for downloading the file. I omit checks and/or security issues.
def download_report
#Warning: a mechanism should be implemented to prevent the remote
#client from faking the path and download other files.
#A possible solution would be providing not only the file path but also a
#hash with a secret key to validate the path. Function create_csv_file()
#should, then, return a hash in addition of a path.
path = params[:report]
file = File.open(path, "rb")
contents = file.read
file.close
send_data(contents , :type => 'text/csv', :filename => 'users.csv')
file.unlink #Delete file
end