Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import CSV Data in a Rails App with ActiveAdmin

i want to upload CSV files through the activeadmin panel.

on the index page from the resource "product" i want a button next to the "new product" button with "import csv file".

i dont know where to start. in the documentation is something about collection_action, but with the code below i have no link at the top.

ActiveAdmin.register Post do     collection_action :import_csv, :method => :post do       # Do some CSV importing work here...       redirect_to :action => :index, :notice => "CSV imported successfully!"     end   end 

anyone here who use activeadmin and can import csv data?

like image 886
user993460 Avatar asked Oct 13 '11 13:10

user993460


People also ask

Where should I put CSV in rails?

To me it made the most sense to place by CSV file in the lib folder in my Rails API project directory. You may place your file where it makes most sense to you. In Ruby, you can import your CSV file all at once (which stores all of the file content in memory) or read from the file one row at a time.


2 Answers

Continuing from Thomas Watsons great start to the answer which helped me get my bearings before figuring the rest of it out.

The code blow allows not just CSV upload for the example Posts model but for any subsequent models thereafter. all you need to do is copy the action_item ands both collection_actions from the example into any other ActiveAdmin.register block and the functionality will be the same. hope this helps.

app/admin/posts.rb

ActiveAdmin.register Post do   action_item :only => :index do     link_to 'Upload CSV', :action => 'upload_csv'   end    collection_action :upload_csv do     render "admin/csv/upload_csv"   end    collection_action :import_csv, :method => :post do     CsvDb.convert_save("post", params[:dump][:file])     redirect_to :action => :index, :notice => "CSV imported successfully!"   end  end 

app/models/csv_db.rb

require 'csv' class CsvDb   class << self     def convert_save(model_name, csv_data)       csv_file = csv_data.read       CSV.parse(csv_file) do |row|         target_model = model_name.classify.constantize         new_object = target_model.new         column_iterator = -1         target_model.column_names.each do |key|           column_iterator += 1           unless key == "ID"             value = row[column_iterator]             new_object.send "#{key}=", value           end         end         new_object.save       end     end   end end 

note: this example does a check to see whether or not the first column is an ID column, it then skips that column as rails will assign an ID to the new object (see example CSV below for reference)

app/views/admin/csv/upload_csv.html.haml

= form_for :dump, :url=>{:action=>"import_csv"}, :html => { :multipart => true } do |f|   %table     %tr       %td         %label{:for => "dump_file"}           Select a CSV File :       %td         = f.file_field :file     %tr       %td         = submit_tag 'Submit' 

app/public/example.csv

"1","TITLE EXAMPLE","MESSAGE EXAMPLE","POSTED AT DATETIME" "2","TITLE EXAMPLE","MESSAGE EXAMPLE","POSTED AT DATETIME" "3","TITLE EXAMPLE","MESSAGE EXAMPLE","POSTED AT DATETIME" "4","TITLE EXAMPLE","MESSAGE EXAMPLE","POSTED AT DATETIME" "5","TITLE EXAMPLE","MESSAGE EXAMPLE","POSTED AT DATETIME" 

note: quotations not always needed

like image 111
ben.m Avatar answered Sep 27 '22 20:09

ben.m


Adding a collection_action does not automatically add a button linking to that action. To add a button at the top of the index screen you need to add the following code to your ActiveAdmin.register block:

action_item :only => :index do   link_to 'Upload CSV', :action => 'upload_csv' end 

But before calling the collection action you posted in your question, you first need the user to specify which file to upload. I would personally do this on another screen (i.e. creating two collection actions - one being a :get action, the other being your :post action). So the complete AA controller would look something like this:

ActiveAdmin.register Post do   action_item :only => :index do     link_to 'Upload posts', :action => 'upload_csv'   end    collection_action :upload_csv do     # The method defaults to :get     # By default Active Admin will look for a view file with the same     # name as the action, so you need to create your view at     # app/views/admin/posts/upload_csv.html.haml (or .erb if that's your weapon)   end    collection_action :import_csv, :method => :post do     # Do some CSV importing work here...     redirect_to :action => :index, :notice => "CSV imported successfully!"   end end 
like image 36
Thomas Watson Avatar answered Sep 27 '22 22:09

Thomas Watson