使用ActiveAdmin在Rails应用程序中导入CSV数据

use*_*460 25 csv ruby-on-rails-3.1 activeadmin

我想通过activeadmin面板上传CSV文件.

在资源"产品"的索引页面上,我想要一个带有"import csv file"的"new product"按钮旁边的按钮.

我不知道从哪里开始.在文档中是关于collection_action的东西,但是使用下面的代码我顶部没有链接.

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
Run Code Online (Sandbox Code Playgroud)

这里有谁使用activeadmin并可以导入csv数据?

ben*_*n.m 42

继续托马斯·沃特森(Thomas Watsons)的伟大开端,帮助我在确定剩下的部分之前得到了答案.

代码打击不仅允许示例Posts模型的CSV上传,还允许其后的任何后续模型.您需要做的就是将action_item和示例中的collection_actions复制到任何其他ActiveAdmin.register块中,功能将相同.希望这可以帮助.

应用程序/管理/ 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
Run Code Online (Sandbox Code Playgroud)

应用程序/模型/ 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
Run Code Online (Sandbox Code Playgroud)

注意:此示例检查第一列是否为ID列,然后跳过该列,因为rails将为新对象分配ID(请参阅下面的示例CSV以供参考)

应用程序/视图/管理/ 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'
Run Code Online (Sandbox Code Playgroud)

应用程序/公/ 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"
Run Code Online (Sandbox Code Playgroud)

注意:并不总是需要报价


Tho*_*son 13

添加a collection_action不会自动添加链接到该操作的按钮.要在索引屏幕顶部添加按钮,您需要将以下代码添加到ActiveAdmin.register块中:

action_item :only => :index do
  link_to 'Upload CSV', :action => 'upload_csv'
end
Run Code Online (Sandbox Code Playgroud)

但在调用您在问题中发布的收集操作之前,首先需要用户指定要上载的文件.我个人会在另一个屏幕上执行此操作(即创建两个集合操作 - 一个是:get操作,另一个是您的:post操作).所以完整的AA控制器看起来像这样:

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
Run Code Online (Sandbox Code Playgroud)


Fiv*_*ell 6

@krhorst,我试图使用你的代码,但不幸的是它很糟糕的大进口.它吃了太多的内存=(所以我决定使用基于activerecord-import gem的自己的解决方案

这是https://github.com/Fivell/active_admin_import

特征

  1. 编码处理
  2. 支持使用ZIP文件导入
  3. 两步导入(参见示例2)
  4. CSV选项
  5. 能够自动添加CSV标头
  6. 批量导入(activerecord-import)
  7. 能够自定义模板
  8. 回调支持
  9. 支持从zip文件导入
  10. ....