我有一个数据对象,其中包含许多用于各种输入的attr_accessor字段。我可以以某种方式定义类,以便所有字段的所有设置器将例如将值设置为空字符串而不是尝试的nil?
答案 0 :(得分:9)
这是一个小模块:
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
将它混合在一起:
class Foo
extend NilToBlankAttrAccessor
nil_to_blank_attr_accessor :bar
end
并使用它:
foo = Foo.new
foo.bar = nil
p foo.bar # => ""
foo.bar = 'abc'
p foo.bar # => "abc"
工作原理
NilToBlankAttrAccessor#nil_to_blank_attr_accessor
首先定义attr_reader:
attr_reader attr
然后它通过定义一个与访问者同名的方法来定义编写器,最后只有一个“=”。因此,对于属性:bar
,该方法名为bar=
define_method "#{attr}=" do |value|
...
end
现在需要设置变量。首先,它将nil变为空字符串:
value = '' if value.nil?
然后使用instance_variable_set,它执行实例变量赋值,其中直到运行时才知道实例变量。
instance_variable_set "@#{attr}", value
Class Foo需要nil_to_blank_attr_accessor作为类方法,而不是实例方法,所以它使用extend
代替include
:
class Foo
extend NilToBlankAttrAccessor
...
end
答案 1 :(得分:1)
而不是做
object.foo = given_input
你应该做
object.foo = given_input.nil? ? "" : given_input
或者如果您想将false
转换为""
,那么
object.foo = given_input || ""