Rails 数据库字段序列化
场景展现
发布活动的 WebApp
假如你在开发一个发布活动的 WebApp , 那么 contests 数据库表有一个 judges 字段。活动评委有多个的情况下你是怎么把多个评委保存在 judges 字段中呢?
从数据库层面来说,postgresql 和非关系型数据库 mongodb 自持数组类型的字段,但是 mysql 数据库却不支持数组类型的字段。
用户个人信息存储
假如你系统需要记录用户的个人偏好。譬如用户语言,国籍或者肤色等多种个人信息。有一种比较傻瓜的方式就是逐个信息建立对应的字段,但是这些个人信息一多的话,那岂不是在 users 表建立了很多字段,有没有一种方式在一个字段中哈希健值对的形式把这些个人信息保存起来呢?
{ "language" => "Chinese", "country" => "China" ... }
Rails 能把任何中对象序列化保存在 text 类型的字段中
Rails 的 Serialization API 能把 Arrary, Hash, JSON 这样的结构的数据序列化成对象保存在类型为 text 的字段中。那么,通过这种方式能够答疑上述两个问题。
Keep in mind that database adapters handle certain serialization tasks for you. For instance: json and jsonb types in PostgreSQL will be converted between JSON object/array syntax and Ruby Hash or Array objects transparently. There is no need to use serialize in this case.
注意:支持 Hash, Array, JSON 字段类型的数据库(比如 PostgreSQL)就没必要使用 serialize 了。
Rails serialize 用法
API 是这样定义的:
serialize(attr_name, class_name_or_coder = Object)
实际的例子如下:
# Serialize preferences as Hash using YAML coder.
class User < ActiveRecord::Base
serialize :preferences, Hash
end
新建和查询:
user = User.create(preferences: { "background" => "black", "display" => large })
User.find(user.id).preferences # => { "background" => "black", "display" => large }
回到上文提到的场景一,在 contest model 中添加serialize :judges, Array
那么新增 contest 记录时 judges 字段对应的值为一个数组
contest = Contest.create(judges: ["张三","李四"], ...)
查询
Contest.find(contest.id).judges #=> ["张三","李四"]
Note
If you have serialized column in your model then this column will always be updated when you update your model, even though you make no changes to the values in that selialized column. So don't try to use this extensively in your app as it could affect the overall performance.
继续阅读:
Rails serialize API
Saving arrays, hashes, and other non-mappable objects in text columns
ruby-china 能用 mysql 吗?