Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions lib/strip_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ def strip_attributes(options = {})

before_validation(options.slice(:if, :unless)) do |record|
StripAttributes.strip(record, options)
# Mark that stripping has been done to avoid double processing
record.instance_variable_set(:@attributes_stripped, true)
end

# Also add before_save to handle save(validate: false) scenarios
# Only run if validation was skipped (attributes not already stripped)
if respond_to?(:before_save)
before_save do |record|
unless record.instance_variable_get(:@attributes_stripped)
StripAttributes.strip(record, options)
end
# Reset the flag after save for next operation
record.instance_variable_set(:@attributes_stripped, false)
end
end
end
end
Expand Down
7 changes: 7 additions & 0 deletions test/strip_attributes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,13 @@ def test_should_strip_no_fields_if_false_proc
assert_equal " ", record.bang
end

def test_should_strip_on_save_without_validation
record = StripAllMockRecord.new(foo: " ")
record.save(validate: false)

assert_nil record.foo, "Expected empty string ' ' to be converted to nil"
end

class ClassMethodsTest < Minitest::Test
def test_should_strip_whitespace
assert_nil StripAttributes.strip("")
Expand Down
17 changes: 17 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ class Tableless
include ActiveAttr::Serialization

include ActiveModel::Validations::Callbacks

# Simple mock of save callbacks for testing
extend ActiveModel::Callbacks
define_model_callbacks :save

# Mock save method that respects validate: false option
def save(options = {})
if options[:validate] == false
# When validate: false, skip validation but still run save callbacks
run_callbacks :save
else
# Normal save: run validation callbacks then save callbacks
run_callbacks :validation
run_callbacks :save
end
true
end
end

# Avoid annoying deprecation warning
Expand Down