我有一个ActiveRecord模型,其 字段来自数据库。还有其他属性,来自嵌套的序列化blob。这样做是为了让我可以使用表单中的这些属性,而不必跳过箍(或者我在开始时考虑过),同时允许向前和向后兼容,而无需编写复杂的迁移。
基本上我这样做:
class Licence < ActiveRecord::Base
attr_accessor :load_worker_count
strip_attributes!
validates_numericality_of :load_worker_count,
:greater_than => 2, :allow_nil => true, :allow_blank => true
before_save :serialise_fields_into_properties
def serialise_fields_into_properties
...
end
def after_initialize
...
end
...
end
我注意到的问题是我无法在:load_worker_count
中获得验证者接受的空值,因为:
:allow_blank
,则无法通过验证将其归为空白:allow_blank
,它会将空白转换为0,而:greater_than => 2
在追踪这些空白值首先进入验证阶段的原因时,我发现了问题的根源: strip_attributes!
仅影响{{1}返回的实际属性方法。因此验证时应为零的值不是。因此,感觉就像根本原因是在设置剥离属性时看不到我添加的合成属性,因此我要问:
是否有正确的方法来创建合成属性,这些属性被与ActiveRecord集成的其他代码识别为正确的属性?
答案 0 :(得分:1)
我假设你在谈论strip_attributes
插件;查看代码时,它使用在active_record / base.rb中定义的方法attributes
,该方法使用@attributes
,它被初始化(在initialize
中)为@attributes = attributes_from_column_definition
。< / p>
也许有可能以某种方式破解ActiveRecord :: Base,但这将是一项艰苦的工作:{/ 1}}在从/向db发送/放入内容时也会使用,所以你必须做很多黑客攻击
有一个更简单的解决方案:
@attributes
毕竟,这就是strip_attributes!确实
答案 1 :(得分:1)
在这里使用Rails的序列化宏会不会更容易?
class License < ActiveRecord::Base
serialize :special_attributes
end
现在您可以为special_attributes分配一个哈希或数组或任何您需要的东西,Rails会将它序列化为数据库中的文本字段。
license = License.new
license.special_attributes = { :beer => true, :water => false }
这将保持您的代码清洁,您不必担心自己序列化/反序列化属性。