在Rails 3.2中修改Postgres JSON字段时出错

Fil*_*Kis 3 postgresql ruby-on-rails ruby-on-rails-3.2 postgresql-9.3

我正在尝试在我的Rails 3.2应用程序中使用JSON(Postgres 9.3,而不是JSONB)字段类型.

我已经使用以下迁移创建了该字段而没有任何问题:

def change
  add_column :blocks, :meta, :json
end
Run Code Online (Sandbox Code Playgroud)

但是,当我试图像这样修改字段时:

b.meta = {name: "John"}
b.save
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

ActiveRecord::StatementInvalid: PGError: ERROR:  invalid input syntax for type json
LINE 1: UPDATE "blocks" SET "meta" = '---
Run Code Online (Sandbox Code Playgroud)

我甚至不确定Rails 3.2中是否支持JSON类型,但我已经看到一些帖子尽可能地谈论它(虽然没有关于它是如何工作的细节).

Jor*_*ing 6

我认为你是正确的,Rails 3中的ActiveRecord本身不支持JSON.您的错误的原因是,给定复杂的数据类型(在本例中为Hash),ActiveRecord将首先将其序列化为字符串,默认序列化为YAML.这就是---您的错误消息中的内容 - 它是YAML标头.

一个快速的解决方案是在将Hash分配给您的属性之前将其转换为JSON:

hsh = { name: "John" }
b.meta = hsh.to_json
b.save
Run Code Online (Sandbox Code Playgroud)

不过,这将变得乏味.相反,您可以在序列化此属性时告诉ActiveRecord使用JSON而不是YAML:

class Block < ActiveRecord::Base
  serialize :meta, JSON
end
Run Code Online (Sandbox Code Playgroud)

  • 对于简单的对象,我认为你不会看到很多性能影响,如果有的话.对于大型,深层嵌套的对象,您可能会这样,但很难说.一直是性能问题的答案:如果您真的需要知道,请对其进行分析.我不知道ActiveRecord 4.2的JSON支持如何比较.看起来性能应该非常相似,但AR 4.2可能会做一些我不知道的缓存或其他优化. (2认同)