在一个声明中使用ActiveRecord序列化多个属性?

时间:2013-06-13 20:45:58

标签: ruby-on-rails ruby activerecord

我的模型包含大约10个属性,我希望在我的数据库中将其序列化为JSON

有办法吗?

serialize attribute1, JSON
// ...
serialize attribute10, JSON

单行?因为serialize [attribute1, ..., attribute10], JSON不起作用。

谢谢!

4 个答案:

答案 0 :(得分:7)

根据您在此处尝试的内容,store实际上可能更适合您:

store :settings, accessors: :attr1, :attr2, :attr3

Rails将使用单个列来存储(和序列化)多个属性,并且它将为每个属性定义访问器,因此您仍然可以像访问单个列一样访问它们。

我提出这个的原因是因为你在数据库中使用单独的列来获得任何额外的价值是相对不太可能的,因为大多数关系数据库都不会对它做任何特殊的事情。您的应用程序效率更高,并且在添加需要类似处理的其他项时,您不必继续向数据库添加列。

我使用此模式存储与用户相关的社交网址。当下一个网络出现时,我只需添加一个存取器和一个表单字段,我们就设置了,不需要迁移。


顺便说一句,Rails 4还支持指定使用的编码器。即:

store :settings, accessors: [ :attr1, :attr2, :attr3 ], coder: JSON

答案 1 :(得分:1)

很抱歉,根据文档不确定这是否可以开箱即用:

http://apidock.com/rails/ActiveRecord/AttributeMethods/Serialization/ClassMethods/serialize

否则,您可以创建一个覆盖ActiveRecord并执行您希望它执行的操作的模块。

答案 2 :(得分:0)

根据user1376019推荐,我使用的解决方案如下:

json_exclusions = ["id", "column_not_serialized"]
YourModel.column_names.reject{|col| json_exclusions.include?(col)}.each{|attr| serialize attr, JSON}

我选择了这条路线,因为我正在使用的模型的大多数属性都是序列化的,但您可能会发现直接列出序列化属性以提高效率。

答案 3 :(得分:0)

如果方便的话对你有用,你可以定义一种新的方法来更优雅地处理它:

module SerializeAll
  def serialize_all(*columns)
    store = columns.last.is_a?(Module) ? columns.pop : JSON

    columns.each do |column|
      serialize column, store
    end
  end
end

class Model < ActiveRecord::Base
  extend SerializeAll
  serialize_all :attr1, :attr2, :attr3, JSON
end

如果您考虑splat,这与serialize具有相同的意义,但也有些令人困惑。实现serialize_all的另一种方法与Ruby(和Rails)中的许多其他方法更加一致,就是使用extract_options!,如果它存在,它将从数组的末尾拉出一个哈希:

def serialize_all(*columns)
  options = columns.extract_options!
  # ... serialize(column, options[:store])
end

serialize_all :attr1, :attr2, :attr3, store: JSON

主要只是偏好问题。您也可以,如果您在应用程序的其他位置使用此功能,请继续将其包含在ActiveRecord::Base中。