Skip to content

Commit

Permalink
Add option that allows stripping of whitespace for all values (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
littleforest committed May 12, 2023
1 parent 2e3900a commit ee78b32
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 4 deletions.
18 changes: 17 additions & 1 deletion README.md
Expand Up @@ -140,13 +140,14 @@ ArtVandelay::Import.new(model_name, **options)
|Argument|Description|
|--------|-----------|
|`model_name`|The name of the model being imported. E.g. `:users`, `:user`, `"users"` or `"user"`|
|`**options`|A hash of options. Available options are `rollback:`|
|`**options`|A hash of options. Available options are `rollback:`, `strip:`|

#### Options

|Option|Description|
|------|-----------|
|`rollback:`|Whether the import should rollback if any of the records fails to save.|
|`strip:`|Strips leading and trailing whitespace from all values, including headers.|

#### ArtVandelay::Import#csv

Expand Down Expand Up @@ -221,6 +222,21 @@ result = ArtVandelay::Import.new(:users).csv(csv_string, attributes: {email_addr
# => #<ArtVandelay::Import::Result>
```

##### Stripping whitespace

```ruby
csv_string = CSV.generate do |csv|
csv << ["email_address ", " passcode "]
csv << [" george@vandelay_industries.com ", " bosco "]
end

result = ArtVandelay::Import.new(:users, strip: true).csv(csv_string, attributes: {email_address: :email, passcode: :password})
# => #<ArtVandelay::Import::Result>

result.rows_accepted
# => [{:row=>["george@vandelay_industries.com", "bosco"], :id=>1}]
```

## 🙏 Contributing

1. Run `./bin/setup`.
Expand Down
15 changes: 12 additions & 3 deletions lib/art_vandelay.rb
Expand Up @@ -142,6 +142,7 @@ def initialize(rows_accepted:, rows_rejected:)
def initialize(model_name, **options)
@options = options.symbolize_keys
@rollback = options[:rollback]
@strip = options[:strip]
@model_name = model_name
end

Expand All @@ -164,7 +165,7 @@ def csv(csv_string, **options)

private

attr_reader :model_name, :rollback
attr_reader :model_name, :rollback, :strip

def active_record
model_name.to_s.classify.constantize
Expand All @@ -177,8 +178,16 @@ def build_csv(csv_string, headers)
def build_params(row, attributes)
attributes = attributes.stringify_keys

row.to_h.stringify_keys.transform_keys do |key|
attributes[key] || key
if strip
row.to_h.stringify_keys.transform_keys do |key|
attributes[key.strip] || key.strip
end.tap do |new_params|
new_params.transform_values!(&:strip)
end
else
row.to_h.stringify_keys.transform_keys do |key|
attributes[key] || key
end
end
end

Expand Down
40 changes: 40 additions & 0 deletions test/art_vandelay_test.rb
Expand Up @@ -336,6 +336,26 @@ class Import < ArtVandelayTest
assert_equal "s3kure!", user_2.password
end

test "it strips whitespace when strip configuration is passed" do
csv_string = CSV.generate do |csv|
csv << [" email ", " password "]
csv << [" email_1@example.com ", " s3krit "]
csv << [" email_2@example.com ", " s3kure! "]
end

assert_difference("User.count", 2) do
ArtVandelay::Import.new(:users, strip: true).csv(csv_string)
end

user_1 = User.find_by!(email: "email_1@example.com")
user_2 = User.find_by!(email: "email_2@example.com")

assert_equal "email_1@example.com", user_1.email
assert_equal "s3krit", user_1.password
assert_equal "email_2@example.com", user_2.email
assert_equal "s3kure!", user_2.password
end

test "it sets the headers" do
csv_string = CSV.generate do |csv|
csv << %w[email_1@example.com s3krit]
Expand Down Expand Up @@ -375,6 +395,26 @@ class Import < ArtVandelayTest
assert_equal "s3kure!", user_2.password
end

test "strips whitespace if strip configuration is passed when using custom attributes" do
csv_string = CSV.generate do |csv|
csv << ["email_address ", " passcode "]
csv << [" email_1@example.com ", " s3krit "]
csv << [" email_2@example.com", " s3kure! "]
end

assert_difference("User.count", 2) do
ArtVandelay::Import.new(:users, strip: true).csv(csv_string, attributes: {:email_address => :email, "passcode" => "password"})
end

user_1 = User.find_by!(email: "email_1@example.com")
user_2 = User.find_by!(email: "email_2@example.com")

assert_equal "email_1@example.com", user_1.email
assert_equal "s3krit", user_1.password
assert_equal "email_2@example.com", user_2.email
assert_equal "s3kure!", user_2.password
end

test "it no-ops if one record fails to save" do
csv_string = CSV.generate do |csv|
csv << %w[email password]
Expand Down

0 comments on commit ee78b32

Please sign in to comment.