activerecord-typedstore icon indicating copy to clipboard operation
activerecord-typedstore copied to clipboard

Add example for usage with Postgres jsonb columns

Open Jurawa opened this issue 8 years ago • 4 comments

Just wanted to let you know I had some issues getting this setup when using a Postgres jsonb column...

My first implementation did not include a custom coder, and when updating a typed_store attribute, I got this error:

ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR:  invalid input syntax for type json
DETAIL:  Token "-" is invalid.
CONTEXT:  JSON data, line 1: -...
: UPDATE "companies" SET "settings" = $1, "updated_at" = $2 WHERE "companies"."id" = $3

Which is because it was using the default yaml coder.

However, when I added the DumbCoder, I got a TypeError: can't cast Hash to error.

It was all solved by just using the JSON coder:

typed_store :settings, coder: JSON do |s|
    s.boolean :foo, default: true, null: false
end

I think this would be useful to add to the readme...

Cheers!

Jurawa avatar Jun 15 '16 00:06 Jurawa

+1 @rafaelfranca

rainerborene avatar Mar 09 '18 17:03 rainerborene

But the json string seems escaped with coder: JSON :/

dinatih avatar Mar 15 '18 17:03 dinatih

I'm not a PostgreSQL user. I'm fine with adding it, but to be fair I don't know the solution for the problem so I'd rely on someone sending a PR.

rafaelfranca avatar Mar 15 '18 21:03 rafaelfranca

The following JSONB example includes:

  • Full example model class
  • How to specify the correct coder, including the current require workaround needed
  • How to generate the migration
  • An example JSONB query (specific to PostgreSQL)
  • A validates for one of the accessors with a default value to workaround the create! issue (https://github.com/byroot/activerecord-typedstore/issues/37)
# won't need to do this require in the next release of `activerecord-typedstore`
require 'active_record/typed_store/identity_coder'

class Foo < ApplicationRecord
  typed_store :details, coder: ActiveRecord::TypedStore::IdentityCoder do |s|
    s.boolean :public, default: false, null: false
    s.string :email
    s.datetime :publish_at
    s.integer :age, null: false

    # You can define array attributes like in rails 4 and postgres
    s.string :tags, array: true, default: [], null: false

    # In addition to prevent null values you can prevent blank values
    s.string :title, blank: false, default: 'Title'

    # If you don't want to enforce a datatype but still like to have default handling
    s.any :source, blank: false, default: 'web'
  end

  # You can use any ActiveModel validator
  validates :age, presence: true
end

Migration: bin/rails generate migration CreateFoo details:jsonb

Using the class from a console (mine has a name field and timestamps, you can ignore them): image

jcw- avatar Feb 09 '19 08:02 jcw-