Skip to content

Commit e4552fd

Browse files
committed
Merge pull request #35 from Fivell/csv_replacements
Csv replacements
2 parents e87d406 + 0e2e8aa commit e4552fd

File tree

6 files changed

+89
-3
lines changed

6 files changed

+89
-3
lines changed

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,25 @@ Tool | Description
178178
}
179179
end
180180
```
181-
182-
#### Example7 dynamic CSV options, template overriding
181+
182+
#### Example7 change csv values before import (find each 'Author name' column and replace it with authors_id before insert )
183+
184+
```ruby
185+
ActiveAdmin.register Post do
186+
active_admin_import validate: true,
187+
headers_rewrites: { :'Author name' => :author_id },
188+
before_batch_import: ->(importer) {
189+
authors_names = importer.values_at(:author_id)
190+
# replacing author name with author id
191+
authors = Author.where(name: authors_names).pluck(:name, :id)
192+
options = Hash[*authors.flatten] # #{"Jane" => 2, "John" => 1}
193+
importer.batch_replace(:author_id, options)
194+
}
195+
end
196+
```
197+
198+
199+
#### Example8 dynamic CSV options, template overriding
183200

184201
- put overrided template to ```app/views/import.html.erb```
185202

lib/active_admin_import/importer.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,30 @@ def import_options
4949
@import_options ||= options.slice(:validate, :on_duplicate_key_update, :ignore, :timestamps)
5050
end
5151

52+
def batch_replace(header_key, options)
53+
index = header_index(header_key)
54+
csv_lines.map! do |line|
55+
from = line[index]
56+
line[index] = options[from] if options.has_key?(from)
57+
line
58+
end
59+
end
60+
61+
def values_at(header_key)
62+
csv_lines.collect { |line| line[header_index(header_key)] }.uniq
63+
end
64+
65+
def header_index(header_key)
66+
headers.values.index(header_key)
67+
end
68+
5269
protected
5370

5471
def process_file
5572
lines, batch_size = [], options[:batch_size].to_i
5673
File.open(file.path) do |f|
5774
# capture headers if not exist
58-
prepare_headers{ CSV.parse(f.readline, @csv_options).first }
75+
prepare_headers { CSV.parse(f.readline, @csv_options).first }
5976
f.each_line do |line|
6077
lines << line if line.present?
6178
if lines.size == batch_size || f.eof?

spec/fixtures/files/posts.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"Title","Body","Author Name"
2+
"title1","some body","John"
3+
"title2","some body","Jane"
4+

spec/import_spec.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,41 @@ def upload_file!(name, ext='csv')
4444
find_button('Import').click
4545
end
4646

47+
context "posts index" do
48+
before do
49+
Author.create!(name: 'John', last_name: 'Doe')
50+
Author.create!(name: 'Jane', last_name: 'Roe')
51+
add_post_resource({
52+
validate: true,
53+
headers_rewrites: {
54+
:'Author Name' => :author_id
55+
},
56+
before_batch_import: ->(importer) do
57+
authors_names = importer.values_at(:author_id)
58+
# replacing author name with author id
59+
authors = Author.where(name: authors_names).pluck(:name, :id)
60+
#{"Jane" => 2, "John" => 1}
61+
options = Hash[*authors.flatten]
62+
importer.batch_replace(:author_id, options)
63+
end
64+
})
65+
visit '/admin/posts/import'
66+
upload_file!(:posts)
67+
end
68+
69+
it "should resolve author_id by author name" do
70+
Post.all.each do |post|
71+
expect(Author.where(id: post.author.id)).to be_present
72+
end
73+
end
74+
75+
it "should be imported" do
76+
expect(Post.count).to eq(2)
77+
expect(page).to have_content "Successfully imported 2 posts"
78+
end
79+
80+
end
81+
4782
context "authors index" do
4883
before do
4984
add_author_resource

spec/support/admin.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,14 @@ def add_author_resource(options = {}, &block)
77
Rails.application.reload_routes!
88

99
end
10+
11+
12+
def add_post_resource(options = {}, &block)
13+
14+
ActiveAdmin.register Post do
15+
config.filters = false
16+
active_admin_import(options, &block)
17+
end
18+
Rails.application.reload_routes!
19+
20+
end

spec/support/rails_template.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# Rails template to build the sample app for specs
22

33
generate :model, 'author name:string{10}:uniq last_name:string birthday:date'
4+
generate :model, 'post title:string:uniq body:text author:references'
45

56
#Add validation
67
inject_into_file "app/models/author.rb", " validates_presence_of :name\n", after: "Base\n"
8+
inject_into_file "app/models/post.rb", " validates_presence_of :author\n", after: ":author\n"
79

810
# Configure default_url_options in test environment
911
inject_into_file "config/environments/test.rb", " config.action_mailer.default_url_options = { :host => 'example.com' }\n", after: "config.cache_classes = true\n"

0 commit comments

Comments
 (0)