27

activeadmin パネルから CSV ファイルをアップロードしたい。

リソース「製品」のインデックスページで、「csvファイルのインポート」を含む「新製品」ボタンの横にボタンが必要です。

どこから始めたらいいのかわからない。ドキュメントには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

activeadmin を使用して csv データをインポートできる人はいますか?

4

7 に答える 7

45

トーマス・ワトソンズから続けて、残りの部分を理解する前に自分の方向性を理解するのに役立った答えへの素晴らしいスタートを切りました。

コードブローでは、投稿モデルの例だけでなく、それ以降のモデルのCSVアップロードも可能です。必要なのは、action_itemと両方のcollection_actionsを例から他のActiveAdmin.registerブロックにコピーすることだけで、機能は同じになります。お役に立てれば。

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

注:この例では、最初の列がID列であるかどうかを確認し、レールが新しいオブジェクトにIDを割り当てるため、その列をスキップします(以下のCSVの例を参照してください)。

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"

注:引用は必ずしも必要ではありません

于 2012-03-25T09:13:07.640 に答える
14

を追加しcollection_actionても、そのアクションにリンクするボタンは自動的に追加されません。インデックス画面の上部にボタンを追加するには、次のコードをActiveAdmin.registerブロックに追加する必要があります。

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

ただし、質問に投稿したコレクション アクションを呼び出す前に、まずユーザーがアップロードするファイルを指定する必要があります。個人的には別の画面でこれを行います (つまり、2 つのコレクション アクションを作成します。1 つは:getアクションで、もう1 つはユーザーの: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
于 2011-10-13T14:34:35.540 に答える
9

@krhorst、私はあなたのコードを使用しようとしていましたが、残念ながら大きなインポートには対応していません。それは非常に多くのメモリを消費します=(したがって、activerecord-import gemに基づく独自のソリューションを使用することにしました

こちらですhttps://github.com/Fivell/active_admin_import

特徴

  1. エンコード処理
  2. ZIPファイルでのインポートをサポート
  3. 2 段階のインポート (例 2 を参照)
  4. CSV オプション
  5. CSV ヘッダーを自動的に付加する機能
  6. 一括インポート (activerecord-import)
  7. テンプレートをカスタマイズする機能
  8. コールバックのサポート
  9. zipファイルからのインポートをサポート
  10. ....
于 2013-03-11T15:53:51.720 に答える
0

ben.m の応答を拡張すると、非常に役立つことがわかりました。

CSV インポート ロジック (属性が整列せず、列イテレータが必要に応じて機能しない) に問題があり、代わりに行ごとのループと model.create メソッドを利用する変更を実装しました。これにより、ヘッダー行が属性と一致する .csv をインポートできます。

アプリ/モデル/csv_db.rb

require 'csv'
class CsvDb
  class << self
    def convert_save(model_name, csv_data)
      csv_file = csv_data.read
      lines = CSV.parse(csv_file)
      header = lines.shift
      lines.each do |line|
        attributes = Hash[header.zip line]
        target_model = model_name.classify.constantize
        target_model.create(attributes)
      end
    end
  end
end

したがって、インポートされた CSV ファイルは次のようになります (モデル属性と一致させるために使用します)。

importExample.csv

first_name,last_name,attribute1,attribute2
john,citizen,value1,value2
于 2014-08-28T02:45:44.513 に答える