Search code examples
ruby-on-railspostgresqlruby-on-rails-5jsonb

Should I default jsonb to '{}' or {} in migration


Of the scarce instructions I've read about adding Postgres's data type jsonb in a migration, it's looking like this:

create_table :ref_check_ins do |t|
  t.jsonb :document, null: false, default: '{}'
  t.index :document, using: :gin
end

But is there any reason against defaulting to Hash intead of String, i.e. {} instead of '{}' ?

When defining it to String type, the class of that column:

String < Object

When defining it to Hash type, the class of that column:

Hash

Solution

  • In the migration file, you're going to want to use the {} vs '{}'.

    I literally just was struggling this for a while, and the thing is is that I think the PG adapter implicitly knows how to convert a hash to a jsonb object. It's not like the json type in the postgres DB, where you're storing a string value of a json object, but an actual binary object (in jsonb). I can probably dig it up in the Rails 4.2 release code somewhere, but, if you're looking that the thin documentation on it (which I'm going to be adding to in the near future), the key here is that you're actually getting a string back from Postgres when you do '{}', and thus when you try to indifferent_access it, it fails, because a string can't have indifferent access. That was probably my first headsup that there was a few issues with the info they were providing.

    I honestly don't use the straight up {} anyhow, favoring [] over {}, because usually I'm handling very specific logging functionality I want explicit on a record without having to join two large tables together. That's my particular use case here on 5.0, and it might be a bit different if you're <5, but probably not by much.