madeintandem / jsonb_accessor

Adds typed jsonb backed fields to your ActiveRecord models.
MIT License
1.1k stars 93 forks source link

ArgumentError: unknown type :jsonb #70

Closed marclennox closed 7 years ago

marclennox commented 7 years ago

In updating to 1.0.0.beta3, I started to get these errors. Reverting to beta2 "fixes" it for me. Does this error indicate anything useful on its own?

crismali commented 7 years ago

Off the top of my head I'm not sure why that error would be happening. Can you provide your call to jsonb_accessor and when this error happens? (Is it when the class loads? When you run a certain query? Some other situation?)

marclennox commented 7 years ago

Hi @crismali, it looks like this is happening on class loading. I've seen it happen a lot when my sidekiq workers are starting up, but it seems to correct itself after causing some initial havoc. I am also seeing it during a rake db:seed operation trying to load my Sprig database seeds in development.

For the seeds error, it looks like the jsonb_accessor call in question is the following:

jsonb_accessor :properties,
                   time_zone: :string,
                   device_wake_window_start: [:string, default: '00:00'],
                   device_wake_window_end: [:string, default: '04:00']
crismali commented 7 years ago

@marclennox I'm not able to reproduce the error with ActiveRecord 5.0. My guess is that since you're specifying defaults, Jsonb Accessor is specifying them for the properties column, but the :jsonb type doesn't seem to exist.

Give it a shot without the defaults and see if the error goes away. If it does go away, then it's probably pretty solvable over here. If not, we'll have to dig in more. Either way, could you provide your ActiveRecord version, pg gem version, and Postgres version?

marclennox commented 7 years ago

Yep, removing the defaults fixes the issue.

activerecord-5.0.2 pg-0.20.0 postgres 9.6.2

crismali commented 7 years ago

Could you also provide the information on the column from your schema.rb?

marclennox commented 7 years ago
t.jsonb "properties", default: {}, null: false
crismali commented 7 years ago

It looks like Spring just isn't loading the ActiveRecord column types. It also looks like Spring might have some more general compatibility issues with Rails 5 (this issue isn't the same problem your experiencing but it does indicate to me that they probably don't play very nice with one another at the moment).

A possible workaround would be to require active_record/connection_adapters/postgresql_adapter from ActiveRecord somewhere in your Spring or Application config.

marclennox commented 7 years ago

Thanks @crismali , I tried your suggested workaround, to no avail. But I also get this error outside of the sprig environment when my sidekiq workers start up.

marclennox commented 7 years ago

Oh and just to be clear, I'm not using the rails Spring framework, I was referring to the sprig seed gem https://github.com/vigetlabs/sprig

marclennox commented 7 years ago

I've removed the defaults and used accessor method overrides to handle defaults instead. This has resolved the problem for all cases.

crismali commented 7 years ago

Ah, cool, didn't know about sprig. I'm glad you were able to workaround the problem. Another solution might be to change the properties column default to a hash that contains your actual defaults. That way you wouldn't have to override the getters ¯\_(ツ)_/¯

Anyway, I think I'm going to close this since it seems like a problem in Rails (that is, if you didn't have the jsonb accessor gem at all and called attribute :properties, :jsonb, default: { "foo" => "bar" } I believe you'd run into the same error. (Definitely willing to reopen if that starts working in Rails but breaking here though).

Thanks for all of the information you provided! 👍

jamespearson commented 7 years ago

I've been able to replicate the issue, with or without defaults in the Rails migration.

This will cause the error:

  jsonb_accessor :meta,
                 orientation: [:string, default: "landscape"]

This will not:

  jsonb_accessor :meta,
                 orientation: :string

The table is as follows:

#
#  id           :integer          not null, primary key
#  title        :string
#  meta         :jsonb
#  created_at   :datetime         not null
#  updated_at   :datetime         not null
#

The full error is:

ArgumentError: Unknown type :jsonb
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activemodel-5.0.3/lib/active_model/type/registry.rb:20:in `lookup'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/type.rb:37:in `lookup'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/attributes.rb:236:in `block in load_schema!'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/attributes.rb:234:in `each'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/attributes.rb:234:in `load_schema!'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/attribute_decorators.rb:28:in `load_schema!'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/model_schema.rb:437:in `load_schema'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/model_schema.rb:339:in `columns_hash'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/querying.rb:41:in `find_by_sql'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/relation.rb:702:in `exec_queries'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/relation.rb:583:in `load'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/relation.rb:260:in `records'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/relation.rb:256:in `to_a'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/relation/finder_methods.rb:563:in `find_nth_with_limit'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/relation/finder_methods.rb:592:in `find_nth_with_limit_and_offset'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/relation/finder_methods.rb:545:in `find_nth'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/relation/finder_methods.rb:122:in `first'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.3/lib/active_record/querying.rb:3:in `first'
    from (irb):1
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/railties-5.0.3/lib/rails/commands/console.rb:65:in `start'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/railties-5.0.3/lib/rails/commands/console_helper.rb:9:in `start'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/railties-5.0.3/lib/rails/commands/commands_tasks.rb:78:in `console'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/railties-5.0.3/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
    from /Users/jspearson/.rvm/gems/ruby-2.4.0/gems/railties-5.0.3/lib/rails/commands.rb:18:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'
jamespearson commented 7 years ago

FYI: It occurs only on the first attempt to access the database. On the second attempt everything runs perfectly.

crismali commented 7 years ago

@jamespearson does this error occur if you call attribute :meta, :jsonb, default: { "orientation" => "landscape" } without any calls to jsonb_accessor?

jamespearson commented 7 years ago

@crismali - Yes, exactly the same error when using

attribute :meta, :jsonb, default: { "orientation" => "landscape" }

jaybloke commented 7 years ago

Receiving the same problem when trying to set a default.

I'm using 'postgis' for my db adapter in database.yml - If I replace with the regular 'postgresql' adapter the problem appears to go away.

Had to revert to beta 2 in order to get this to play nicely with my set up.

Gems included by the bundle:
  * actioncable (5.1.3)
  * actionmailer (5.1.3)
  * actionpack (5.1.3)
  * actionview (5.1.3)
  * activejob (5.1.3)
  * activemodel (5.1.3)
  * activerecord (5.1.3)
  * activerecord-postgis-adapter (5.0.2)
  * activesupport (5.1.3)
  * addressable (2.5.2)
  * annotate (2.7.2)
  * arel (8.0.0)
  * awesome_print (1.8.0)
  * bcrypt (3.1.11)
  * builder (3.2.3)
  * bundler (1.15.4)
  * byebug (9.1.0)
  * climate_control (0.2.0)
  * cocaine (0.5.8)
  * coderay (1.1.2)
  * concurrent-ruby (1.0.5)
  * countries (2.1.2)
  * database_cleaner (1.6.1)
  * diff-lcs (1.3)
  * erubi (1.6.1)
  * factory_girl (4.8.0)
  * factory_girl_rails (4.8.0)
  * faker (1.8.4)
  * ffi (1.9.18)
  * formatador (0.2.5)
  * geocoder (1.4.4)
  * globalid (0.4.0)
  * guard (2.14.1)
  * guard-compat (1.2.1)
  * guard-rspec (4.7.3)
  * i18n (0.8.6)
  * i18n_data (0.8.0)
  * jsonb_accessor (1.0.0.beta.3)
  * listen (3.1.5)
  * loofah (2.0.3)
  * lumberjack (1.0.12)
  * mail (2.6.6)
  * maxminddb (0.1.14)
  * method_source (0.8.2)
  * mime-types (3.1)
  * mime-types-data (3.2016.0521)
  * mimemagic (0.3.2)
  * mini_portile2 (2.2.0)
  * minitest (5.10.3)
  * money (6.9.0)
  * nenv (0.3.0)
  * nio4r (2.1.0)
  * nokogiri (1.8.0)
  * notiffany (0.1.1)
  * paperclip (5.1.0)
  * pg (0.21.0)
  * phony (2.15.48)
  * pry (0.10.4)
  * public_suffix (3.0.0)
  * puma (3.10.0)
  * rack (2.0.3)
  * rack-test (0.6.3)
  * rails (5.1.3)
  * rails-dom-testing (2.0.3)
  * rails-html-sanitizer (1.0.3)
  * railties (5.1.3)
  * rake (12.0.0)
  * rb-fsevent (0.10.2)
  * rb-inotify (0.9.10)
  * rgeo (0.6.0)
  * rgeo-activerecord (5.1.0)
  * rspec (3.6.0)
  * rspec-core (3.6.0)
  * rspec-expectations (3.6.0)
  * rspec-mocks (3.6.0)
  * rspec-rails (3.6.1)
  * rspec-support (3.6.0)
  * ruby_dep (1.5.0)
  * shellany (0.0.1)
  * shoulda-matchers (3.1.2)
  * sixarm_ruby_unaccent (1.2.0)
  * slop (3.6.0)
  * spring (2.0.2)
  * spring-watcher-listen (2.0.1)
  * sprockets (3.7.1)
  * sprockets-rails (3.2.1)
  * strip_attributes (1.8.0)
  * terminal-notifier-guard (1.7.0)
  * thor (0.20.0)
  * thread_safe (0.3.6)
  * tzinfo (1.2.3)
  * unicode_utils (1.4.0)
  * websocket-driver (0.6.5)
  * websocket-extensions (0.1.2)
  * word-count-validator (1.0.0)
crismali commented 7 years ago

@jamespearson and @jaybloke It looks like you both have the same problem which is the database adapter you're using doesn't know about the jsonb type. To workaround that you could require ActiveRecord::Type::Jsonb (you may also need to register it `ActiveRecord::Type.register(:jsonb, ActiveRecord::Type::Jsonb). Depending on your version of rails is might be in a different directory.

jhirn commented 6 years ago

I opened https://github.com/rgeo/activerecord-postgis-adapter/issues/267 with the postgis adapter. Not fully understanding why the postgis adapter doesn't get all of the postgresql types registered but there's a work around in that issue.