export CSV by rails
I will not save a file, just make it downloaded by Tempfile.
I will not use database table, of course.
This is how my form looks (in new page)
config/routes.rb file
resources :accounts, only: [:new, :create]
app/views/accounts/new.html.erb file
<%= form_with url: accounts_path, local: true do |f| %>
<%= f.text_area :names, rows: 10, required: true %>
<p>Add account names separated by newline.</p>
<%= f.submit 'Export CSV' %>
<% end %>
When the form is submitted, it triggers create action. Form submit of form_with makes POST request to accounts_path with parameters. And rails syntax resources :accounts makes create action of accounts controller triggered by that POST request.
And this is not a model backed form. Sometimes simple things look difficult or not possible because the other complicated things look too easy. ActiveRecord is not needed (something like @account in the form) in this case, because we are not going to save anything.
app/controllers/accounts_controller.rb file
class AccountsController < ApplicationController
def create
# ...
end
end
At this point params[:names] is available in create method. (we call it an ‘action’ because it’s a method in a rails controller) So, we can use user input from the form here.
This is for instagram accounts. I wanted to show this code because this tool does not work. So do not use it for fetching data from instagram.
def create
headers = ['account_name', 'business_email', 'business']
filename = "business emails #{Date.today}.csv"
Tempfile.open do |tempfile|
CSV.open(tempfile.path, "wb", write_headers: true, headers: headers) do |csv|
params[:names].split("\r\n").each do |account_name|
account_name = account_name.tr(' ', '')
uri = URI("https://www.instagram.com/#{account_name}/?__a=1")
res = Net::HTTP.get_response(uri)
if res.is_a?(Net::HTTPSuccess)
body = JSON(res.body)
business_email = body['graphql']['user']['business_email']
is_business = body['graphql']['user']['is_business_account']
csv << [account_name, business_email, is_business]
end
end
end
send_data File.read(tempfile.path), filename: filename, type: 'text/csv'
end
end
ruby Tempfile is used and CSV is used (you may need require 'csv' on top of the file). I put everything in the Tempfile.open block because everything should happen before the tempfile is closed. Other than that, some net/http code is used.
So now we can generate / export a CSV file without saving a file, without database. Thank you