Hap*_*off 15 activerecord ruby-on-rails
我有一个带有一些属性和虚拟属性的模型.此虚拟属性用于在创建表单中创建一个复选框.
class Thing < ActiveRecord::Base
attr_accessor :foo
attr_accessible :foo
end
Run Code Online (Sandbox Code Playgroud)
由于该字段是表单中的复选框,因此该foo属性将接收'0'或'1'作为值.我希望它是一个布尔值,因为以下代码:
class Thing < ActiveRecord::Base
attr_accessor :foo
attr_accessible :foo
before_validation :set_default_bar
private
def set_default_bar
self.bar = 'Hello' if foo
end
end
Run Code Online (Sandbox Code Playgroud)
这里的问题是条件即使在时foo也是如此'0'.我想使用ActiveRecord类型的转换机制,但我发现只有以下内容:
class Thing < ActiveRecord::Base
attr_reader :foo
attr_accessible :foo
before_validation :set_default_bar
def foo=(value)
@foo = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
end
private
def set_default_bar
self.bar = 'Hello' if foo
end
end
Run Code Online (Sandbox Code Playgroud)
但我觉得这样做很脏.没有重写转换方法,有没有更好的选择?
谢谢
Tyl*_*ick 15
原始帖子的解决方案对我来说是最好的解决方案.
class Thing < ActiveRecord::Base
attr_reader :foo
def foo=(value)
@foo = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
end
end
Run Code Online (Sandbox Code Playgroud)
如果你想稍微清理一下,你总是可以创建一个帮助器方法,foo=为你定义你的编写器方法value_to_boolean.
我可能会创建一个带有调用方法的模块,bool_attr_accessor因此您可以将模型简化为如下所示:
class Thing < ActiveRecord::Base
bool_attr_accessor :foo
end
Run Code Online (Sandbox Code Playgroud)
似乎ActiveModel应该为我们提供这样的东西,因此虚拟属性更像是"真实"(ActiveRecord-persisted)属性.只要您具有从表单提交的布尔虚拟属性,此类型转换就非常重要.
也许我们应该向Rails提交补丁......
在 Rails 5 中,您可以使用attribute方法。此方法在此模型上定义具有类型的属性。如果需要,它将覆盖现有属性的类型。
class Thing < ActiveRecord::Base
attribute :foo, :boolean
end
Run Code Online (Sandbox Code Playgroud)
注意:attribute在从数据库加载的模型上,rails 5.0.0中此功能的行为不正确。因此使用 rails 5.0.1 或更高版本。