Mark Locklear
Mark Locklear

Reputation: 5325

Download CSV in rails 3.2

I am trying to download some model data from a search page to a csv file. Here is the relevant code:

config/application.rb

require 'csv'

controller

  def find_by_registration_date
    @registration_date = params[:registration_date]
    @registrations = Registration.where("DATE(created_at) = ? ", @registration_date)
    respond_to do |format|
      format.html
      format.csv { send_data Registrations.to_csv(@registrations) }
    end
  end

model

  def self.to_csv(options = {})
    CSV.generate(options) do |csv|
      csv << column_names
      all.each do |registration|
        csv << registration.attributes.values_at(*column_names)
      end
    end
  end

EDIT: When I try this I get the error:

TypeError in RegistrationsController#find_by_registration_date

can't convert ActiveRecord::Relation into Hash

Rails.root: /home/johnmlocklear/railsApps/nso
Application Trace | Framework Trace | Full Trace

app/models/registration.rb:43:in `to_csv'
app/controllers/registrations_controller.rb:139:in `block (2 levels) in find_by_registration_date'

app/controllers/registrations_controller.rb:137:in `find_by_registration_date'

EDIT: This is so odd. If I do something like:

  def find_by_registration_date
    @registrations = Registration.order :first_name 
    respond_to do |format|
      format.html
      format.csv { send_data @registrations.to_csv }
    end
  end

...then it works as expected. I'm assuming that one of these methods is returning an array, and another is returning a hash?

Upvotes: 0

Views: 403

Answers (1)

Mark Locklear
Mark Locklear

Reputation: 5325

Here is what I ended up with...

app/views/registrations/find_by_registration_date.html.erb

<%= link_to 'Export CSV', csv_path(registration_date: @registration_date) %>

routes.rb

  match 'csv' => 'registrations#export_csv', :as => :csv

app/controllers/registrations_controller.rb

  def export_csv
    @registration_date = params[:registration_date]
    @registrations = Registration.where("DATE(created_at) = ? ", @registration_date)
    csv = CSV.generate do |csv|
      csv << ["last_name", "id"]
       @registrations.each do |r|
         csv << [r.last_name, r.student_id]
       end
     end
     send_data(csv, :type => 'test/csv', :filename => 'add_hoc.csv')
  end

Goes against the 'skinny controller/fat model' paradigm, but works for now.

Upvotes: 2

Related Questions