17

Postgres の JSON データ型を使い始めたのは、それを使ってできる楽しいことがたくさんあるからです。まだRails 4ではない私のRailsアプリの1つ(Postgres JSONのサポートが追加されている場所)で、次のようなJSON列を追加しました:

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

しかし、列のデフォルト値を設定する方法がわかりません。{}'{}'、などのすべてのバリエーションを試しましたが、移行の実行時にエラーが発生するか、単に機能しない、つまり移行は実行されますが、新しい を'{}'::json作成すると.'[]'::jsonFoobarnil

4

3 に答える 3

31

少し遅れましたが、これでうまくいきました (Postgres >= 9.3 が必要です):

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

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

編集:この回答は、to_json('[]'::text)代わりに支持するために使用されていました-ヒントについては@Offirmo'[]'::JSONに感謝します。

古い方法の問題点は、実際には配列やオブジェクトをデフォルト値として定義するのではなく、そのように見えるスカラー(文字列) を定義することでした。なぜそれが重要なのですか?

Postgres では、次の 3 種類の値を JSON 列に挿入できます。

  1. オブジェクト

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

  2. 配列

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

  3. スカラー

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

問題は、これら 3 種類を同じ列に混在させると、JSON 演算子を使用できなくなることです。以前に提唱された方法を使用して「[]」のデフォルトを設定し、配列要素を照会した場合、スカラーのデフォルト値を持つ単一の行に遭遇すると、クエリ全体がエラーで中止されます。

=# SELECT * FROM foo WHERE bar->>1 = 'baz';
ERROR:  cannot extract element from a scalar
于 2013-12-23T15:13:06.887 に答える
5

以下のコードは、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 = '{}';"

アプリケーション.rb

config.active_record.schema_format = :sql
于 2014-04-13T21:11:40.200 に答える