在Rails中为Postgres JSON列设置默认值< 4

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Rails中为Postgres JSON列设置默认值< 4相关的知识,希望对你有一定的参考价值。

所以,我开始使用Postgres JSON数据类型,现在 有很多有趣的东西,你可以用它来做。.在我的一个Rails应用中,它还不是Rails 4(在那里)。增加了对Postgres JSON的支持。) 我添加了一个JSON列,像这样。

create_table :foo do |t|
  t.column :bar, :json
end

但我不知道如何为该列设置一个默认值,我尝试了所有的变化,比如 {}, '{}', '{}'::json, '[]'::json 等,但我要么在迁移运行时得到一个错误,要么就是根本就不工作,也就是说迁移运行了,但是,当我创建一个新的 Foo, barnil.

答案

虽然有点晚了,但这对我来说是可行的(需要Postgres >= 9.3)。

create_table :foo do |t|
  t.column :bar, :json
end

execute "ALTER TABLE foo ALTER COLUMN bar SET DEFAULT '[]'::JSON"

EDIT: 这个答案曾经倡导 to_json('[]'::text) 而不是 '[]'::JSON - 由于 @Offirmo 的提示。

旧方法的问题是,它实际上并没有像人们期望的那样定义一个数组或对象作为默认值,而是定义了一个 标量 纫,看起来像一个。为什么要这样做呢?

Postgres允许在JSON列中插入三种值。

  1. 对象

    INSERT INTO foo (bar) VALUE('{}')

  2. 数组

    INSERT INTO foo (bar) VALUE('[]')

  3. 疤痕

    INSERT INTO foo (bar) VALUE('"string"')

问题是,如果把这三种混合在同一列中,就失去了使用JSON运算符的能力。如果你用之前提倡的方法设置了'[]'的默认值,并查询一个数组元素,遇到单行的标量默认值,会以错误的方式中止整个查询。

=# SELECT * FROM foo WHERE bar->>1 = 'baz';
ERROR:  cannot extract element from a scalar
另一答案

以下代码适用于PostgreSQL 9.3.4和Rails 3.2.17。

class YourModel < ActiveRecord::Base
...
  serialize :your_column, JSON
  before_create do
    self.your_column ||= {}
  end
...
end

迁移代码

add_column :your_table, :your_column, :json
execute "ALTER TABLE your_table ALTER COLUMN your_column SET DEFAULT '{}'"
execute "UPDATE your_table SET your_column = '{}';"

application.rb

config.active_record.schema_format = :sql
另一答案

基本上你可以做这样的事情

create_table :foo do |t|
  t.column :bar, :json, default: []
end

用以下方式说明默认情况 default: []default: {} 或其他任何你觉得舒服的东西。

更新:请注意,这是针对Rails 4+的。

以上是关于在Rails中为Postgres JSON列设置默认值< 4的主要内容,如果未能解决你的问题,请参考以下文章

使用 Rails 5 在 Postgres 中存储字符串化 JSON

Rails 5.2 API - 在JSON中返回枚举值

rails - postgres 或 rails 是不是自动验证 datetime 列只能具有 datetime 对象?

Rails 弄乱了我的 Postgres TIME 列

将 .json 文件数据加载到 Postgres for Rails 5 API

如何在Postgres中为表中的虚拟列创建数据库链接?