Skip to content

Commit 8d78ff9

Browse files
committed
Merge pull request #41 from activeadmin-plugins/import_with_particular_foreign_key
spec for predefined foreign_key
2 parents c52cd47 + 9447434 commit 8d78ff9

File tree

4 files changed

+92
-67
lines changed

4 files changed

+92
-67
lines changed

lib/active_admin_import/importer.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
module ActiveAdminImport
33
class Importer
44

5-
attr_reader :resource, :options, :result, :headers, :csv_lines, :model
5+
attr_reader :resource, :options, :result, :model
6+
attr_accessor :csv_lines, :headers
67

78
OPTIONS = [
89
:validate,
@@ -85,7 +86,7 @@ def process_file
8586
end
8687

8788
def prepare_headers
88-
headers = self.headers.present? ? self.headers : yield
89+
headers = self.headers.present? ? self.headers.map(&:to_s) : yield
8990
@headers = Hash[headers.zip(headers.map { |el| el.underscore.gsub(/\s+/, '_') })].with_indifferent_access
9091
@headers.merge!(options[:headers_rewrites].symbolize_keys.slice(*@headers.symbolize_keys.keys))
9192
@headers
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"Title","Body"
2+
"title1","some body"
3+
"title2","some body"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
"title1","some body"
2+
"title2","some body"

spec/import_spec.rb

Lines changed: 84 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
expect(author.last_name).to be_present
2222
end
2323
end
24-
2524
end
2625

2726
def with_zipped_csv(name, &block)
@@ -36,7 +35,6 @@ def with_zipped_csv(name, &block)
3635
ensure
3736
File.delete zip_file rescue nil
3837
end
39-
4038
end
4139

4240
def upload_file!(name, ext='csv')
@@ -48,35 +46,85 @@ def upload_file!(name, ext='csv')
4846
before do
4947
Author.create!(name: "John", last_name: "Doe")
5048
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)
6749
end
6850

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
51+
context "for csv for particular author" do
52+
let(:author) { Author.take }
53+
54+
shared_examples 'successful inserts for author' do
55+
it "should use predefined author_id" do
56+
expect(Post.where(author_id: author.id).count).to eq(Post.count)
57+
end
58+
59+
it "should be imported" do
60+
expect(Post.count).to eq(2)
61+
expect(page).to have_content "Successfully imported 2 posts"
62+
end
63+
end
64+
65+
context "no headers" do
66+
before do
67+
add_post_resource(template_object: ActiveAdminImport::Model.new(author_id: author.id,
68+
csv_headers: [:title, :body, :author_id]),
69+
validate: true,
70+
before_batch_import: ->(importer) do
71+
importer.csv_lines.map! { |row| row << importer.model.author_id }
72+
end
73+
)
74+
75+
visit "/admin/posts/import"
76+
upload_file!(:posts_for_author_no_headers)
77+
end
78+
include_examples 'successful inserts for author'
7279
end
73-
end
7480

75-
it "should be imported" do
76-
expect(Post.count).to eq(2)
77-
expect(page).to have_content "Successfully imported 2 posts"
81+
context "with headers" do
82+
before do
83+
add_post_resource(template_object: ActiveAdminImport::Model.new(author_id: author.id),
84+
validate: true,
85+
before_batch_import: ->(importer) do
86+
importer.csv_lines.map! { |row| row << importer.model.author_id }
87+
importer.headers.merge!({ :'Author Id' => :author_id })
88+
end
89+
)
90+
91+
visit "/admin/posts/import"
92+
upload_file!(:posts_for_author)
93+
end
94+
include_examples 'successful inserts for author'
95+
end
7896
end
7997

98+
context "for csv with author name" do
99+
before do
100+
add_post_resource(
101+
validate: true,
102+
template_object: ActiveAdminImport::Model.new,
103+
headers_rewrites: { :'Author Name' => :author_id },
104+
before_batch_import: ->(importer) do
105+
authors_names = importer.values_at(:author_id)
106+
# replacing author name with author id
107+
authors = Author.where(name: authors_names).pluck(:name, :id)
108+
#{"Jane" => 2, "John" => 1}
109+
options = Hash[*authors.flatten]
110+
importer.batch_replace(:author_id, options)
111+
end
112+
)
113+
visit "/admin/posts/import"
114+
upload_file!(:posts)
115+
end
116+
117+
it "should resolve author_id by author name" do
118+
Post.all.each do |post|
119+
expect(Author.where(id: post.author.id)).to be_present
120+
end
121+
end
122+
123+
it "should be imported" do
124+
expect(Post.count).to eq(2)
125+
expect(page).to have_content "Successfully imported 2 posts"
126+
end
127+
end
80128
end
81129

82130
context "authors index" do
@@ -91,27 +139,21 @@ def upload_file!(name, ext='csv')
91139
find_link('Import Authors').click
92140
expect(current_path).to eq("/admin/authors/import")
93141
end
94-
95-
96142
end
97143

98144
context "with custom block" do
99-
100-
101145
before do
102146
add_author_resource({}) do
103147
flash[:notice] = 'some custom message'
104148
end
105149
visit '/admin/authors/import'
106-
107150
end
108151

109152
it "should display notice from custom block" do
110153
upload_file!(:author)
111154
expect(page).to have_content "some custom message"
112155
end
113156

114-
115157
end
116158

117159
context "authors already exist" do
@@ -122,11 +164,11 @@ def upload_file!(name, ext='csv')
122164

123165
context "having authors with the same Id" do
124166
before do
125-
add_author_resource({
126-
before_batch_import: ->(importer) do
127-
Author.where(id: importer.values_at("id")).delete_all
128-
end
129-
})
167+
add_author_resource(
168+
before_batch_import: ->(importer) do
169+
Author.where(id: importer.values_at("id")).delete_all
170+
end
171+
)
130172
visit "/admin/authors/import"
131173
upload_file!(:authors_with_ids)
132174
end
@@ -136,13 +178,11 @@ def upload_file!(name, ext='csv')
136178
expect(Author.count).to eq(2)
137179
end
138180

139-
it "should replace authors by id" do
181+
it "should replace authors by id" do
140182
expect(Author.find(1).name).to eq("John")
141183
expect(Author.find(2).name).to eq("Jane")
142184
end
143-
144185
end
145-
146186
end
147187

148188
context "with valid options" do
@@ -154,7 +194,6 @@ def upload_file!(name, ext='csv')
154194
visit '/admin/authors/import'
155195
end
156196

157-
158197
it "has valid form" do
159198
form = find('#new_active_admin_import_model')
160199
expect(form['action']).to eq("/admin/authors/do_import")
@@ -209,17 +248,14 @@ def upload_file!(name, ext='csv')
209248
end
210249

211250
context "BOM" do
212-
213251
it "should import file with many records" do
214252
upload_file!(:authors_bom)
215253
expect(page).to have_content "Successfully imported 2 authors"
216254
expect(Author.count).to eq(2)
217255
end
218-
219256
end
220257

221258
context "with headers" do
222-
223259
it "should import file with many records" do
224260
upload_file!(:authors)
225261
expect(page).to have_content "Successfully imported 2 authors"
@@ -231,13 +267,10 @@ def upload_file!(name, ext='csv')
231267
expect(page).to have_content "Successfully imported 1 author"
232268
expect(Author.count).to eq(1)
233269
end
234-
235270
end
236271

237-
238272
context "without headers" do
239273
context "with known csv headers" do
240-
241274
let(:options) do
242275
attributes = { csv_headers: ['Name', 'Last name', 'Birthday'] }
243276
{ template_object: ActiveAdminImport::Model.new(attributes) }
@@ -248,7 +281,6 @@ def upload_file!(name, ext='csv')
248281
expect(page).to have_content "Successfully imported 2 authors"
249282
expect(Author.count).to eq(2)
250283
end
251-
252284
end
253285

254286
context "with unknown csv headers" do
@@ -269,7 +301,6 @@ def upload_file!(name, ext='csv')
269301
end
270302

271303
context "with invalid records" do
272-
273304
context "with validation" do
274305
it "should render error" do
275306
upload_file!(:author_invalid)
@@ -278,31 +309,25 @@ def upload_file!(name, ext='csv')
278309
end
279310
end
280311

281-
282312
context "without validation" do
283313
let(:options) { { validate: false } }
284314
it "should render error" do
285315
upload_file!(:author_invalid)
286316
expect(page).to have_content "Successfully imported 1 author"
287317
expect(Author.count).to eq(1)
288318
end
289-
290319
end
291-
292-
293320
end
294321

295322
context "when zipped" do
296323
context "when allowed" do
297-
298324
it "should import file" do
299325
with_zipped_csv(:authors) do
300326
upload_file!(:authors, :zip)
301327
expect(page).to have_content "Successfully imported 2 authors"
302328
expect(Author.count).to eq(2)
303329
end
304330
end
305-
306331
end
307332

308333
context "when not allowed" do
@@ -321,9 +346,8 @@ def upload_file!(name, ext='csv')
321346
end
322347

323348
context "with different header attribute names" do
324-
325349
let(:options) do
326-
{ headers_rewrites: {:'Second name' => :last_name} }
350+
{ headers_rewrites: { :'Second name' => :last_name } }
327351
end
328352

329353
it "should import file" do
@@ -334,7 +358,6 @@ def upload_file!(name, ext='csv')
334358
end
335359

336360
context "with semicolons separator" do
337-
338361
let(:options) do
339362
attributes = { csv_options: { col_sep: ";" } }
340363
{ template_object: ActiveAdminImport::Model.new(attributes) }
@@ -346,21 +369,18 @@ def upload_file!(name, ext='csv')
346369
expect(Author.count).to eq(2)
347370
end
348371
end
349-
350372
end
351373

352-
353374
context "with callback procs options" do
354375
let(:options) do
355376
{
356-
before_import: ->(_) { true },
357-
after_import: ->(_) { true },
358-
before_batch_import: ->(_) { true },
359-
after_batch_import: ->(_) { true }
377+
before_import: ->(_) { true },
378+
after_import: ->(_) { true },
379+
before_batch_import: ->(_) { true },
380+
after_batch_import: ->(_) { true }
360381
}
361382
end
362383

363-
364384
it "should call each callback" do
365385
expect(options[:before_import]).to receive(:call).with(kind_of(ActiveAdminImport::Importer))
366386
expect(options[:after_import]).to receive(:call).with(kind_of(ActiveAdminImport::Importer))
@@ -382,5 +402,4 @@ def upload_file!(name, ext='csv')
382402

383403
end
384404

385-
386405
end

0 commit comments

Comments
 (0)