diff --git a/Gemfile.lock b/Gemfile.lock index d88b4bb23d52f9d1290b5ed86c562ba362b981b1..0684b85c4480d45cb511fcff0f51e87ddecf6f70 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,11 +2,20 @@ PATH remote: . specs: excelsior (0.1.0) + activesupport (~> 5.0) simple_xlsx_reader (~> 1.0.2) GEM remote: https://rubygems.org/ specs: + activesupport (5.2.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + concurrent-ruby (1.0.5) + i18n (1.0.1) + concurrent-ruby (~> 1.0) mini_portile2 (2.3.0) minitest (5.11.3) nokogiri (1.8.2) @@ -16,6 +25,9 @@ GEM simple_xlsx_reader (1.0.2) nokogiri rubyzip + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) PLATFORMS ruby diff --git a/README.md b/README.md index b8491fb6f3370b5ed8363b1b9e4bc8c93b1cf108..19b98043ae74a00e49c9e2db0a4a3d7f0d2c97e2 100644 --- a/README.md +++ b/README.md @@ -36,10 +36,21 @@ class UserImporter < Excelsior::Importer end ``` -Then create an instance of your import and run it: +Create an instance of your import and run it. By default it infers the model +to be imported from the classname, e.g.: ```ruby -import = UserImport.new # you may also pass a file per instance here +import = UserImport.new +import.run # calls User.create!(row) for each row +``` + +### Extended API + +You may want to pass an excel file per instance. You can also define your own +import behavior by passing a block to the `run` method: + +```ruby +import = UserImport.new("users/all.xlsx") import.run do |row| User.create!(row) # raise an exception if the data doesn't match your expectations end diff --git a/excelsior.gemspec b/excelsior.gemspec index 550431cd8afb24d40471d20efa57150ee0c12471..2ebc5299cbbfa382e8656bef2aa34d20dd91b305 100644 --- a/excelsior.gemspec +++ b/excelsior.gemspec @@ -26,4 +26,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "minitest", "~> 5.0" spec.add_runtime_dependency "simple_xlsx_reader", "~> 1.0.2" + spec.add_runtime_dependency "activesupport", "~> 5.0" end diff --git a/lib/excelsior/import.rb b/lib/excelsior/import.rb index cc58cca955a505b73bdc219ac98c04aa9227f3fc..23ed605f0158b5b21afd0eef4c0b6bcf9ea29239 100644 --- a/lib/excelsior/import.rb +++ b/lib/excelsior/import.rb @@ -1,5 +1,6 @@ require "simple_xlsx_reader" - +require "active_support" +require "active_support/core_ext" require "excelsior/source" require "excelsior/mapping" @@ -24,9 +25,14 @@ module Excelsior valid? end - def run(&block) + def run # takes an optional block @rows.map do |row| - yield map_row_values(row, @columns) + attributes = map_row_values(row, @columns) + if block_given? + yield attributes + else + model_class.create!(attributes) + end end end @@ -40,5 +46,11 @@ module Excelsior acc end end + + private + + def model_class + self.class.name.gsub("Import", "").constantize + end end end diff --git a/test/excelsior_test.rb b/test/excelsior_test.rb index 4b6dcb2581c3e651d5fb60b910a7e6d6c947b9dd..536cafca8ba63f3481fbbd47f5493577559d1cfa 100644 --- a/test/excelsior_test.rb +++ b/test/excelsior_test.rb @@ -9,6 +9,19 @@ class UserImport < Excelsior::Import map "E-Mail", to: :email end +class User + class << self + def create!(attributes) + @all ||= [] + @all << attributes + end + + def all + @all ||= [] + end + end +end + class ExcelsiorTest < Minitest::Test def setup @import = UserImport.new @@ -48,6 +61,11 @@ class ExcelsiorTest < Minitest::Test end def test_import_run + results = @import.run + assert_equal User.all.size, 2 + end + + def test_import_run_with_block results = @import.run { |v| v } assert_equal results[0], { firstname: "Hans",