Импорт данных CSV в приложение Rails с ActiveAdmin
Я хочу загрузить CSV файлы через панель activeadmin.
на странице индекса из ресурса "продукт", я хочу кнопку рядом с кнопкой "новый продукт" с "import csv file".
Я не знаю, с чего начать.
в документации есть что-то о 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?
Ответы
Ответ 1
Продолжая с Thomas Watsons отличный ответ на этот вопрос, который помог мне разобраться, прежде чем выдумывать остальную часть.
Удар кода позволяет не только загружать CSV для модели Posts Posts, но и для последующих моделей. все, что вам нужно сделать, это скопировать action_item и оба коллекционных_извлечения из примера в любой другой блок 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
приложение/модели/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: в этом примере проверяется, является ли первый столбец столбцом идентификатора, а затем пропускает этот столбец, поскольку рельсы назначают идентификатор новому объекту (см. пример 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'
приложение/открытый/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"
Примечание: цитаты не всегда нужны
Ответ 2
Добавление collection_action
не добавляет автоматически ссылку на это действие. Чтобы добавить кнопку в верхней части индексного экрана, вам нужно добавить следующий код в блок ActiveAdmin.register
:
action_item :only => :index do
link_to 'Upload CSV', :action => 'upload_csv'
end
Но прежде чем вызывать действие коллекции, опубликованное в вашем вопросе, вам сначала нужно указать, какой файл загрузить. Я лично сделал бы это на другом экране (т.е. Создав два действия коллекции - один из которых - это действие :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 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
Ответ 3
@krhorst, я пытался использовать ваш код, но, к сожалению, он засасывает большие объемы импорта. Он питается так много памяти = (Поэтому я решил использовать собственное решение на основе атрибута activerecord-import
Здесь https://github.com/Fivell/active_admin_import
Функции
- Обработка кодирования
- Поддержка импорта с ZIP-архивом
- Двухэтапный импорт (см. пример2)
- Параметры CSV
- Возможность автоматически добавлять заголовки CSV
- Массовый импорт (activerecord-import)
- Возможность настройки шаблона
- Поддержка обратных вызовов
- Поддержка импорта из zip файла
- ....
Ответ 4
В будущем, я построил драгоценный камень, который позволяет вам легко добавлять импорт csv в активный ресурс admin
См. ссылку
Ответ 5
Основываясь на ben.m отличный ответ выше, я заменил раздел csv_db.rb
, предложенный следующим образом:
require 'csv'
class CsvDb
class << self
def convert_save(model_name, csv_data)
begin
target_model = model_name.classify.constantize
CSV.foreach(csv_data.path, :headers => true) do |row|
target_model.create(row.to_hash)
end
rescue Exception => e
Rails.logger.error e.message
Rails.logger.error e.backtrace.join("\n")
end
end
end
end
Хотя не полный ответ, я не хотел, чтобы мои изменения загрязняли ben.m ответ в случае, если я сделал что-то вопиющее неправильное.
Ответ 6
расширение на 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
Ответ 7
Для большого excel, требующего времени на нормальный процесс, я создал драгоценный камень, который обрабатывает листы Excel с использованием активного задания и отображает результаты с помощью кабеля действия (websockets)
https://github.com/shivgarg5676/active_admin_excel_upload