attr_accessor which transforms nil into string on write
ruby
Solution
Here's a little module to do it:
module NilToBlankAttrAccessor
def nil_to_blank_attr_accessor(attr)
attr_reader attr
define_method "#{attr}=" do |value|
value = '' if value.nil?
instance_variable_set "@#{attr}", value
end
end
end
Just mix it in:
class Foo
extend NilToBlankAttrAccessor
nil_to_blank_attr_accessor :bar
end
And use it:
foo = Foo.new
foo.bar = nil
p foo.bar # => ""
foo.bar = 'abc'
p foo.bar # => "abc"
How it works
`NilToBlankAttrAccessor#nil_to_blank_attr_accessor` first defines the attr_reader normally:
attr_reader attr
Then it defines the writer by defining a method with the same name as the accessor, only with an "=" at the end. So, for attribute `:bar`, the method is named `bar=`
define_method "#{attr}=" do |value|
...
end
Now it needs to set the variable. First it turns nil into an empty string:
value = '' if value.nil?
Then use instance_variable_set, which does an instance variable assignment where the instance variable isn't known until runtime.
instance_variable_set "@#{attr}", value
Class Foo needs nil_to_blank_attr_accessor to be a class method, not an instance method, so it uses `extend` instead of `include`:
class Foo
extend NilToBlankAttrAccessor
...
end
Problem
I have a data object that contains dozens of attr_accessor fields for various inputs. Can I somehow define the class so that all setters for all fields will e.g. set the value as an empty string instead of the attempted nil?