Although a bit late, this worked for me (Postgres> = 9.3 required):
create_table :foo do |t|
t.column :bar, :json
end
execute "ALTER TABLE foo ALTER COLUMN bar SET DEFAULT '[]'::JSON"
EDIT: this answer was used for to_json('[]'::text)
instead of '[]'::JSON
- @Offirmo for a hint.
The problem with the old method was that it did not actually define the array or object as the default, as you might expect, but a scalar (string) that looked like one. Why does it matter?
Postgres allows you to insert three types of values in JSON columns:
The objects
INSERT INTO foo (bar) VALUE('{}')
Arrays
INSERT INTO foo (bar) VALUE('[]')
Scalars
INSERT INTO foo (bar) VALUE('"string"')
, , JSON-. "[]" , :
=# SELECT * FROM foo WHERE bar->>1 = 'baz';
ERROR: cannot extract element from a scalar