空数组作为 active_record 序列化属性的默认值

Posted

技术标签:

【中文标题】空数组作为 active_record 序列化属性的默认值【英文标题】:Empty array as default for active_record serialized attribute 【发布时间】:2011-07-05 06:40:32 【问题描述】:

我有一个活跃的记录模型:

class Person < ActiveRecord::Base
  serialize :tags, Array
end

在迁移中,标签列被声明为

t.text :tags, :default => []

但是当我尝试创建一个人时

Person.new

我得到了错误

ActiveRecord::SerializationTypeMismatch: added was supposed to be a Array, but was a String

迁移中如何设置默认为空数组?

注意:我知道我可以使用 after_initialize 来做到这一点,但我更喜欢在迁移中设置默认值

【问题讨论】:

代替 after_initialize,试试 default_value_for 插件:github.com/FooBarWidget/default_value_for 请注意,您不能在 mysql 中的 TEXT 列上设置默认值,可能还有其他列。 coreyward:有趣,我不知道。看起来这只是 Windows 上的问题bugs.mysql.com/bug.php?id=25520 paul:default_value_for 插件看起来很整洁,如果我找不到迁移的方法,那么我想我会走这条路 我在序列化为Arraystring 列上遇到了同样的问题。一个空数组将产生一个空字符串""。问题是该列有null: falseserialize 想要将[] 序列化为nil。当它不能时,它使用"",但是它不能正确反序列化。 【参考方案1】:

有一个选项可以指定要将对象存储为的类。试试这个:

class Person < ActiveRecord::Base
  serialize :tags, Array
end

【讨论】:

啊,很好,应该在原始帖子中。我已经指定了这个,没有骰子。【参考方案2】:

听起来您遇到了框架错误或其他东西干扰了您的迁移;我刚刚尝试使用 Rails 2.3.10 构建上述内容,并且可以毫无问题地实例化对象。但是,我注意到 YAML 用于序列化,所以:

t.text :tags, :default => [].to_yaml

...也许可以解决问题。在我的测试应用程序中,这两种迁移似乎表现相同。

【讨论】:

是的,我试了一下,它在架构中变成了 "" 而不是 "--- []\n\n" 由于我无法在 Rails 2.3 上复制此错误,因此它要么是 Rails 3 问题,要么是您的应用程序更广泛的问题。但是,以防万一其他地方有关文本列的 cmets 出现在标记上,您是否尝试过使用“t.string”而不是“t.text”,以及最初编写的所有其他代码,只是作为一个实验?哦,您是否尝试过在“serialize”调用中不使用“Array”类说明符?【参考方案3】:

我有一个类似的问题,并通过删除默认值解决了它。 当您开始向数组添加值时,ActiveRecord 会将 nil 视为 []。

Migration:
t.text :tags

Model:
class Person < ActiveRecord::Base
  serialize :tags, Array
end

Usage:
p = Person.new
p.tags << "test" 

这是可行的,因为 Rails 会将 nil 视为数组的 []。

【讨论】:

以上是关于空数组作为 active_record 序列化属性的默认值的主要内容,如果未能解决你的问题,请参考以下文章

尝试反序列化 JSON 对象数组,其中对象具有数组作为属性。我可以将数组元素映射到类的特定属性吗?

如何处理 API 有时将属性作为数组返回,有时作为对象返回?

如何使用 Rest Assured 在 Json 中构造空数组列表

Json(JToken.Parse(response)) 返回空数组

使用空白数组反序列化 JSON 对象

序列化空数组输入[重复]