我有一个Rails 4.2 + MySQL 5.7设置。我已经为原生JSON列创建了一个自定义数据类型,工作正常,但有一个问题 - 如果我设置了默认值,它就不会保留。
具体来说,如果我设置了默认值,则会在实例化时正确设置该属性,但在实例保存时,该字段将不会被识别为已更改,因此无法保存。
这是数据类型定义(以简化形式):
module ActiveRecord
module Type
class Json < Type::Value
include Type::Mutable
def type
:json
end
def type_cast_for_database(value)
case value
when Hash
value.to_json
else
raise "type_cast_for_database not supported: #{value.inspect}"
end
end
def type_cast(value)
case value
when nil
{}
when ::Hash
value
else
raise "type_cast not supported: #{value.inspect}"
end
end
end
end
end
现在,如果我将属性定义为:
attribute :jsfield, ActiveRecord::Type::Json.new, default: {}
在实例化时,将设置该值,但不保存:
instance = MyModel.new
instance.jsfield #=> {}
instance.save # the INSERT will not include the attribute :jsfield
这是由ActiveRecord::Type::Mutable
:
def changed_in_place?(raw_old_value, new_value)
raw_old_value != type_cast_for_database(new_value)
end
它做了正确的事情,但是当设置了默认值时,raw_old_value
被预设(在这种情况下为{}
),因此ActiveRecord认为该值没有改变。
我可以通过允许ActiveRecord::Type::Json#Jsontype_cast
中的nil来解决这个问题 - 但这是唯一的解决方案吗?
我错过了什么吗?