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
    # ...

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]
    send_data File.read(tempfile.path), filename: filename, type: 'text/csv'

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


Now read this

Git Merge your next Change

Sometimes when you want to merge changes made in another branch (in some remote) to your master branch. (or any branch supposed to be working) When you trust and it works fine for sure, then it would be quite simple: git merge And also... Continue →