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?
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With