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

using has_secure_password

For authentication, we need to do following three: to model, has_secure_password to table, password_digest bundle bcrypt gem So, we add has_secure_password to User model, has_secure_password and it requires gem ‘bcrypt-ruby’ to the... Continue →