diff --git a/lib/enumerize/activemodel.rb b/lib/enumerize/activemodel.rb index b57a043..7f2ad16 100644 --- a/lib/enumerize/activemodel.rb +++ b/lib/enumerize/activemodel.rb @@ -50,6 +50,20 @@ def deserialize(value) @attr.find_value(value) end end + + def cast(value) + case value + when nil + return super + when Array + if @attr.arguments[:multiple] + found = @attr.find_values(*value) + return found.presence || super + end + end + + @attr.find_value(value) || value + end end end end diff --git a/test/activemodel_test.rb b/test/activemodel_test.rb index b2c2e52..4056bec 100644 --- a/test/activemodel_test.rb +++ b/test/activemodel_test.rb @@ -183,6 +183,58 @@ class InterestsRequiredActiveModelUser < ActiveModelUser expect(deserialized.map(&:to_s)).must_equal ['music', 'programming'] end end + + describe 'Type#cast' do + it 'casts single valid value to Enumerize::Value' do + type = model.attribute_types['sex'] + result = type.cast('male') + expect(result).must_be_instance_of Enumerize::Value + expect(result.to_s).must_equal 'male' + end + + it 'returns nil for nil single value' do + type = model.attribute_types['sex'] + result = type.cast(nil) + expect(result).must_be_nil + end + + it 'returns original value for invalid single value' do + type = model.attribute_types['sex'] + result = type.cast('invalid') + expect(result).must_equal 'invalid' + end + + it 'casts array of valid values for multiple attribute' do + type = model.attribute_types['interests'] + result = type.cast(['music', 'sports']) + expect(result).must_be_instance_of Array + expect(result.map(&:to_s)).must_equal ['music', 'sports'] + end + + it 'returns empty array as-is for multiple attribute' do + type = model.attribute_types['interests'] + result = type.cast([]) + expect(result).must_equal [] + end + + it 'filters out invalid values when at least one is valid' do + type = model.attribute_types['interests'] + result = type.cast(['music', 'invalid', 'sports']) + expect(result.map(&:to_s)).must_equal ['music', 'sports'] + end + + it 'returns array as-is when all values are invalid for multiple attribute' do + type = model.attribute_types['interests'] + result = type.cast(['invalid1', 'invalid2']) + expect(result).must_equal ['invalid1', 'invalid2'] + end + + it 'returns nil for nil value on multiple attribute' do + type = model.attribute_types['interests'] + result = type.cast(nil) + expect(result).must_be_nil + end + end end else