Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
913ea78
Update .travis.yml
Fivell Mar 17, 2019
722c641
Merge pull request #164 from activeadmin-plugins/bump_ruby_rails
Fivell Mar 17, 2019
1f674cc
refs #163, handle errors on base
Fivell Mar 17, 2019
7e17eb6
Merge pull request #165 from activeadmin-plugins/issue-163
senid231 Mar 17, 2019
5ccf95c
Allow batch_slice_columns to work when batching
doredesign Sep 12, 2019
505743a
Merge pull request #168 from doredesign/fix_batch_slice_columns_while…
workgena Sep 20, 2019
5c43397
bump 4.1.1
workgena Sep 20, 2019
ef68193
Update .gitignore
workgena Sep 20, 2019
08f5f8e
Allow activerecord-import >= 0.27
Dec 10, 2019
e4c42ce
allow application/octet-stream content-type
dmitry-sinina Dec 15, 2019
0f3f143
Merge pull request #172 from dmitry-sinina/application_octet_stream
Fivell Dec 16, 2019
3630c3b
Merge pull request #171 from welcome-travel-technologies/activerecord…
Fivell Dec 16, 2019
a2ebd55
bump 4.1.2
Fivell Dec 16, 2019
198b807
Merge pull request #173 from activeadmin-plugins/4.1.2
Fivell Dec 17, 2019
d1fc7ff
fix uninitialized constant Responders::FlashResponder::ActionView
linqueta Feb 1, 2020
ff3a6e9
Merge pull request #176 from linqueta/fix-rails-5.2.2.1-tests
Fivell Feb 3, 2020
e4e23c9
add active admin import exception
linqueta Jan 30, 2020
0a1c06d
Merge pull request #175 from linqueta/add-active-admin-import-exception
Fivell Feb 5, 2020
5c08253
bump 4.2.0
Fivell Feb 5, 2020
ec3c157
Merge pull request #177 from activeadmin-plugins/release-4-2-0
Fivell Feb 6, 2020
4f2aadc
bump ruby versions
Fivell Feb 6, 2020
07cee9c
Merge pull request #178 from activeadmin-plugins/travis_ruby_versions-1
Fivell Feb 6, 2020
d0efd09
Support for rails 6 (#183)
pnghai Jul 24, 2020
1c7601f
Support for a non UTF-8 file when zip uploading (#185)
naokirin Aug 10, 2020
30858d4
Add compatibility for Ruby 3.0 (#190)
clinejj Nov 10, 2021
a81ce66
drop ruby 2.4 support
Fivell Nov 10, 2021
d3322ea
bump activeadmin dependency
Fivell Nov 10, 2021
672c5c7
bump version
Fivell Nov 10, 2021
2adaa75
ruby/rails versions in travis.yml updated
Fivell Nov 16, 2021
90e82de
changelog updated
Fivell Nov 16, 2021
9ca311a
Migrate to GitHub Actions
enomotodev Dec 30, 2021
5232574
Fix error when passed empty empty csv and model has force_encoding=:auto
Oct 10, 2023
4e83191
Fix error when active_model_import raise ArgumentError Number of valu…
Oct 10, 2023
e6eef78
Merge pull request #200 from BigG1947/fix-errrors-with-invalid-csv
senid231 Oct 11, 2023
a71035e
Fix bugs with cached models
Oct 30, 2023
642bb62
Merge pull request #201 from BigG1947/fix_bugs_with_cashed_model
senid231 Nov 1, 2023
10132e1
rails v7.0 support
gigorok Jun 13, 2023
bf8441c
Merge pull request #199 from activeadmin-plugins/gigorok-patch-1
Fivell Nov 1, 2023
c3d74af
bump v5.1.0
gigorok Nov 2, 2023
160a796
Merge pull request #202 from activeadmin-plugins/bump-v5-1-0
gigorok Nov 2, 2023
27cb9af
add controller context
noslopy Aug 9, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Test

on:
- push
- pull_request

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
ruby_version:
- '2.6'
- '2.7'
- '3.0'
rails_version:
- '5.2.6'
- '6.0.4'
- '6.1.4'
- '7.0.0'
exclude:
- ruby_version: '3.0'
rails_version: '5.2.6'
- ruby_version: '2.6'
rails_version: '7.0.0'

name: Ruby ${{ matrix.ruby_version }} / Rails ${{ matrix.rails_version }}

env:
RAILS: ${{ matrix.rails_version }}

steps:
- uses: actions/checkout@v2

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby_version }}
bundler-cache: true

- name: Test
run: bundle exec rspec spec
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ capybara-*.html
/spec/tmp/*
**.orig
rerun.txt
pickle-email-*.html
pickle-email-*.html
pkg
spec/rails
Gemfile.lock
8 changes: 0 additions & 8 deletions .travis.yml

This file was deleted.

17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
# Changelog
## [5.0.0] - 2021-11-16
- Ruby 3 compatibility added #190 | @clinejj
- Support for a non UTF-8 file when zip uploading #185| @naokirin
- Rails 6 supported #183 | @pnghai
- Drop ruby 2.4 support #192 | @Fivell


## [4.2.0] - 2020-02-05
- generic exception for import added #175 | @linqueta

## [4.1.2] - 2019-12-16
- allow application/octet-stream content-type #172 | @dmitry-sinina
- Allow activerecord-import >= 0.27 #171 | @sagium

## [4.1.1] - 2019-09-20
- Fix column slicing #168 | @doredesign
- Handle errors on base #163

## [4.1.0] - 2019-01-15
- Upgrade dependencies: `activerecord-import` to >=0.27.1 | @jkowens
Expand Down
5 changes: 3 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ gemspec


group :test do
default_rails_version = "~> 5.1"
default_rails_version = "~> 5.2.4"
rails_version = ENV['RAILS'] || default_rails_version
gem 'sassc-rails'
gem 'rails', rails_version
gem 'rspec-rails'
gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io
gem 'sqlite3'
gem "sqlite3", "~> 1.4.0"
gem 'launchy'
gem 'database_cleaner'
gem 'capybara'
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ActiveAdminImport

[![Travis Build ][build_badge]][build_link]
[![Build Status ][build_badge]][build_link]
[![Coverage Status][coveralls_badge]][coveralls_link]
[![Code Climate ][codeclimate_badge]][codeclimate_link]
[![Gem Version ][rubygems_badge]][rubygems_link]
Expand Down Expand Up @@ -91,8 +91,8 @@ Tool | Description
[rchardet]: https://github.com/jmhodges/rchardet
[activerecord-import]: https://github.com/zdennis/activerecord-import

[build_badge]: https://travis-ci.org/activeadmin-plugins/active_admin_import.svg?branch=master
[build_link]: https://travis-ci.org/activeadmin-plugins/active_admin_import
[build_badge]: https://github.com/activeadmin-plugins/active_admin_import/actions/workflows/test.yml/badge.svg
[build_link]: https://github.com/activeadmin-plugins/active_admin_import/actions
[coveralls_badge]: https://coveralls.io/repos/activeadmin-plugins/active_admin_import/badge.svg
[coveralls_link]: https://coveralls.io/github/activeadmin-plugins/active_admin_import
[codeclimate_badge]: https://codeclimate.com/github/activeadmin-plugins/active_admin_import/badges/gpa.svg
Expand Down
8 changes: 4 additions & 4 deletions active_admin_import.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
gem.name = 'active_admin_import'
gem.require_paths = ['lib']
gem.version = ActiveAdminImport::VERSION
gem.add_runtime_dependency 'activerecord-import', '~> 0.27'
gem.add_runtime_dependency 'rchardet', '~> 1.6'
gem.add_runtime_dependency 'rubyzip', '~> 1.2'
gem.add_dependency 'activeadmin', '>= 1.0.0.pre2'
gem.add_runtime_dependency 'activerecord-import', '>= 0.27'
gem.add_runtime_dependency 'rchardet', '>= 1.6'
gem.add_runtime_dependency 'rubyzip', '>= 1.2'
gem.add_dependency 'activeadmin', '>= 1.0.0'
end
1 change: 1 addition & 0 deletions lib/active_admin_import.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'active_admin'
require 'active_admin_import/version'
require 'active_admin_import/engine'
require 'active_admin_import/exception'
require 'active_admin_import/import_result'
require 'active_admin_import/options'
require 'active_admin_import/dsl'
Expand Down
22 changes: 18 additions & 4 deletions lib/active_admin_import/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,14 @@ def active_admin_import(options = {}, &block)
options.assert_valid_keys(*Options::VALID_OPTIONS)

options = Options.options_for(config, options)
params_key = ActiveModel::Naming.param_key(options[:template_object])

collection_action :import, method: :get do
authorize!(ActiveAdminImport::Auth::IMPORT, active_admin_config.resource_class)
@active_admin_import_model = options[:template_object]
@active_admin_import_model = if options[:template_object].is_a?(Proc)
options[:template_object].call
else
options[:template_object]
end
render template: options[:template]
end

Expand All @@ -73,9 +76,15 @@ def active_admin_import(options = {}, &block)

collection_action :do_import, method: :post do
authorize!(ActiveAdminImport::Auth::IMPORT, active_admin_config.resource_class)
options[:controller_context] = self
_params = params.respond_to?(:to_unsafe_h) ? params.to_unsafe_h : params
params = ActiveSupport::HashWithIndifferentAccess.new _params
@active_admin_import_model = options[:template_object]
@active_admin_import_model = if options[:template_object].is_a?(Proc)
options[:template_object].call
else
options[:template_object]
end
params_key = ActiveModel::Naming.param_key(@active_admin_import_model.class)
@active_admin_import_model.assign_attributes(params[params_key].try(:deep_symbolize_keys) || {})
# go back to form
return render template: options[:template] unless @active_admin_import_model.valid?
Expand All @@ -92,7 +101,12 @@ def active_admin_import(options = {}, &block)
else
instance_exec result, options, &DEFAULT_RESULT_PROC
end
rescue ActiveRecord::Import::MissingColumnError, NoMethodError, ActiveRecord::StatementInvalid, CSV::MalformedCSVError => e
rescue ActiveRecord::Import::MissingColumnError,
NoMethodError,
ArgumentError,
ActiveRecord::StatementInvalid,
CSV::MalformedCSVError,
ActiveAdminImport::Exception => e
Rails.logger.error(I18n.t('active_admin_import.file_error', message: e.message))
Rails.logger.error(e.backtrace.join("\n"))
flash[:error] = I18n.t('active_admin_import.file_error', message: e.message[0..200])
Expand Down
5 changes: 5 additions & 0 deletions lib/active_admin_import/exception.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true
module ActiveAdminImport
class Exception < StandardError
end
end
15 changes: 14 additions & 1 deletion lib/active_admin_import/import_result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,21 @@ def failed_message(options = {})
limit = options[:limit] || failed.count
failed.first(limit).map do |record|
errors = record.errors
(errors.full_messages.zip errors.keys.map { |k| record.send k }).map { |ms| ms.join(' - ') }.join(', ')
failed_values = attribute_names_for(errors).map do |key|
key == :base ? nil : record.public_send(key)
end
errors.full_messages.zip(failed_values).map { |ms| ms.compact.join(' - ') }.join(', ')
end.join(' ; ')
end

private

def attribute_names_for(errors)
if Gem::Version.new(Rails.version) >= Gem::Version.new('7.0')
errors.attribute_names
else
errors.keys
end
end
end
end
29 changes: 18 additions & 11 deletions lib/active_admin_import/importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class Importer
:headers_rewrites,
:batch_size,
:batch_transaction,
:csv_options
:csv_options,
:controller_context
].freeze

def initialize(resource, model, options)
Expand All @@ -37,7 +38,7 @@ def file
end

def cycle(lines)
@csv_lines = CSV.parse(lines.join, @csv_options)
@csv_lines = CSV.parse(lines.join, **@csv_options)
import_result.add(batch_import, lines.count)
end

Expand Down Expand Up @@ -70,7 +71,7 @@ def batch_replace(header_key, options)
end
end

# Use it when CSV file contain redundant columns
# Use this method when CSV file contains unnecessary columns
#
# Example:
#
Expand All @@ -81,16 +82,22 @@ def batch_replace(header_key, options)
# end
#
def batch_slice_columns(slice_columns)
use_indexes = []
headers.values.each_with_index do |val, index|
use_indexes << index if val.in?(slice_columns)
# Only set @use_indexes for the first batch so that @use_indexes are in correct
# position for subsequent batches
unless defined?(@use_indexes)
@use_indexes = []
headers.values.each_with_index do |val, index|
@use_indexes << index if val.in?(slice_columns)
end
return csv_lines if @use_indexes.empty?

# slice CSV headers
@headers = headers.to_a.values_at(*@use_indexes).to_h
end
return csv_lines if use_indexes.empty?
# slice CSV headers
@headers = headers.to_a.values_at(*use_indexes).to_h

# slice CSV values
csv_lines.map! do |line|
line.values_at(*use_indexes)
line.values_at(*@use_indexes)
end
end

Expand All @@ -109,7 +116,7 @@ def process_file
batch_size = options[:batch_size].to_i
File.open(file.path) do |f|
# capture headers if not exist
prepare_headers { CSV.parse(f.readline, @csv_options).first }
prepare_headers { CSV.parse(f.readline, **@csv_options).first }
f.each_line do |line|
lines << line if line.present?
if lines.size == batch_size || f.eof?
Expand Down
5 changes: 4 additions & 1 deletion lib/active_admin_import/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module CONST
application/csv
application/vnd.ms-excel
application/vnd.msexcel
application/octet-stream
text/tsv
text/x-tsv
text/tab-separated-values
Expand Down Expand Up @@ -102,14 +103,16 @@ def file_path

def encode_file
data = File.read(file_path)
return if data.empty?

File.open(file_path, 'w') do |f|
f.write(encode(data))
end
end

def unzip_file
Zip::File.open(file_path) do |zip_file|
self.file = Tempfile.new(CONST::TMP_FILE)
self.file = Tempfile.new(CONST::TMP_FILE, binmode: true)
data = zip_file.entries.select(&:file?).first.get_input_stream.read
file << data
file.close
Expand Down
2 changes: 1 addition & 1 deletion lib/active_admin_import/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module Options

def self.options_for(config, options = {})
unless options.key? :template_object
options[:template_object] = ActiveAdminImport::Model.new
options[:template_object] = -> { ActiveAdminImport::Model.new }
end

{
Expand Down
2 changes: 1 addition & 1 deletion lib/active_admin_import/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module ActiveAdminImport
VERSION = '4.1.0'
VERSION = '5.1.0'
end
6 changes: 3 additions & 3 deletions spec/fixtures/files/authors.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Name,Last name,Birthday
John,Doe,1986-05-01
Jane,Roe,1988-11-16
Birthday,Name,Last name
1986-05-01,John,Doe
1988-11-16,Jane,Roe
3 changes: 3 additions & 0 deletions spec/fixtures/files/authors_values_exceeded_headers.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Birthday,Name,Last name
1986-05-01,John,Doe
1988-11-16,Jane,Roe, exceeded value
21 changes: 11 additions & 10 deletions spec/import_result_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
context 'failed_message' do
let(:import_result) { ActiveAdminImport::ImportResult.new }

before do
Author.create(name: 'John', last_name: 'Doe')
Author.create(name: 'Jane', last_name: 'Roe')

let(:failed_instances) do
[
Author.new(last_name: 'Doe').tap {|r| r.errors.add(:last_name, :taken) },
Author.new(name: "", last_name: 'Doe').tap {|r| r.errors.add(:name, :blank); r.errors.add(:last_name, :taken) },
Author.new.tap {|r| r.errors.add(:base, 'custom') }
]
end

before do
@result = double \
failed_instances: [
# {:last_name=>["has already been taken"]}
Author.create(name: 'Jim', last_name: 'Doe'),
# {:name=>["can't be blank"], :last_name=>["has already been taken"]}
Author.create(name: nil, last_name: 'Doe')
]
failed_instances: failed_instances
end

it 'should work without any failed instances' do
Expand All @@ -26,7 +27,7 @@
import_result.add(@result, 4)
expect(import_result.failed_message)
.to eq(
"Last name has already been taken - Doe ; Name can't be blank - , Last name has already been taken - Doe"
"Last name has already been taken - Doe ; Name can't be blank - , Last name has already been taken - Doe ; custom"
)
end

Expand Down
Loading