Thursday, October 6, 2016

Using Ruby CSV Library to Export CSV File in Rails Apps - send_data method Approach

Using Ruby CSV Library to Export CSV File in Rails Apps - send_data method Approach

‘send_data’ method approach

As we mentioned in the previous article, there are two approaches to generate CSV file. Here is the other approach: ‘send_data’ method approach.
The ‘send_data’ method approach use ‘send_data’ method to export data directly to the CSV file in the controller. It does not use the template file, instead, the ‘to_csv’ method is created in the object model. The ‘to_csv’ method utilizes CSV commands to generate data. Then ‘send_data’ method use object.to_csvto export data to the CSV file.
Again, we need to require CSV library in application.rb
app/config/application.rb
require 'csv'  <== add this line
require 'rails/all'
  :
For example, I need a download button on the show page of the model Order. First, I have to add code to the show action of the order controller. ( Actually I manipulate @orderdetails is orders controller )
app/controllers/orders_controller.rb
def show
     :
     :
  respond_to do |format|
    format.html
    fn = "order_#{@order.po_number}_#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}.csv"
    format.csv { send_data @orderdetails.to_csv, filename: fn }
  end
end
Second, a new method .to_csv should be added in Orderdetail model.
app/models/orderdetail.rb
class Orderdetail < ApplicationRecord
    :
    :
  def po_number
    self.order.po_number
  end

  def m_name
    self.model.name
  end

  def s_name
    self.size.name
  end

  def c_name
    self.color.name
  end

  def self.to_csv
    header = ['PO Number','Model Name', 'Size', 'Color', 'Price (USD)', 'Quantity', 'Total Amount']

    attributes = %w{ po_number model_name 
      size_name color_name price quantity 
      total_amount}

    CSV.generate(headers: true) do |csv|
      csv << header

      all.each do |orderdetail|
        csv << attributes.map{ |attr| orderdetail.send(attr) }
      end
    end  
  end
    :
    :  
end
Note that %w(aaa bbb) is a shortcut for [“aaa”, “bbb”]. Meaning it’s a notation to write an array of strings separated by spaces instead of commas and without quotes around them.
The CSV library generates data according to the attributesarray to the csvobject. Then pass it to the function who calls it ( here is the send_datamethod).
While typing the url below in the browser, it downloads the CSV file instantly.
http://localhost:3000/orders/1.csv
Here is the exported CSV file.
File name: order_1234_2016-10-05 23-38-27.csv
PO Number,Model Name,Size,Color,Price (USD),Quantity,Total
1234,PINEROLO AL SE 0.2 TIG welded Sora 18 Carbon/Alloy Fork,700C X 48CM,Gloss Red,365.42,106,38734.52
1234,PINEROLO AL SE 0.2 TIG welded Sora 18 Carbon/Alloy Fork,700C X 48CM,Gloss Black,365.42,2,730.84
1234,PINEROLO AL SE 0.2 TIG welded Sora 18 Carbon/Alloy Fork,700C X 50CM,Gloss Red,365.42,2,730.84
1234,PINEROLO AL SE 0.2 TIG welded Sora 18 Carbon/Alloy Fork,700C X 50CM,Gloss Black,365.42,2,730.84
The last step is to make a link somewhere in the order show page.
app/views/orders/show.html.erb
<%= link_to 'Export to CSV', order_path(@order, format: :csv) %>
Done!

No comments:

Post a Comment