rails_admin: crash on querying models with json columns
If you search / query a model with a jsonb field, and your search query is plain text (like “aa”), then the server will throw a JSON parser exception like the following:
JSON::ParserError (757: unexpected token at '11'):
json (1.8.3) lib/json/common.rb:155:in `parse'
json (1.8.3) lib/json/common.rb:155:in `parse'
rails_admin (0.8.1) lib/rails_admin/config/fields/types/json.rb:17:in `parse_value'
rails_admin (0.8.1) lib/rails_admin/adapters/active_record.rb:121:in `block in query_scope'
rails_admin (0.8.1) lib/rails_admin/adapters/active_record.rb:120:in `each'
rails_admin (0.8.1) lib/rails_admin/adapters/active_record.rb:120:in `query_scope'
rails_admin (0.8.1) lib/rails_admin/adapters/active_record.rb:33:in `all'
rails_admin (0.8.1) app/controllers/rails_admin/main_controller.rb:131:in `get_collection'
rails_admin (0.8.1) app/controllers/rails_admin/main_controller.rb:37:in `list_entries'
rails_admin (0.8.1) lib/rails_admin/config/actions/index.rb:30:in `block (2 levels) in <class:Index>'
rails_admin (0.8.1) app/controllers/rails_admin/main_controller.rb:22:in `instance_eval'
A workaround is to configure the json field as non-queryable.
About this issue
- Original URL
- State: open
- Created 9 years ago
- Reactions: 22
- Comments: 24 (1 by maintainers)
Commits related to this issue
- json.rb now rescues JSON::ParserError Fixing the bug raised in this issue: crash on querying models with json columns https://github.com/sferik/rails_admin/issues/2502 — committed to kevinryantao/rails_admin by kevinryantao 9 years ago
- json.rb now rescues JSON::ParserError Fixing the bug raised in this issue: crash on querying models with json columns https://github.com/sferik/rails_admin/issues/2502 — committed to kevinryantao/rails_admin by kevinryantao 9 years ago
- Fixing TypeError: no implicit conversion of Hash into String crash on querying models with json columns https://github.com/sferik/rails_admin/issues/2502 — committed to kevinryantao/rails_admin by kevinryantao 9 years ago
- Prevent RailsAdmin querying of JSON fields Re: https://github.com/sferik/rails_admin/issues/2502 — committed to europeana/europeana-portal-collections by rwd 6 years ago
Here is my workaround, in an initializer:
Alternatively the following code works too, and does not crash with a 500 error if you enter bad JSON data in a RailsAdmin form:
I improved on @sbull’s solution by making it work with the current rails_admin version (1.4.2) at the time of writing:
The advantage of this technique is that it does not force you to eager load your app.
Note for Rails 5 (or any situation where you have an abstract model defined like ApplicationRecord), you’ll need to skip abstract classes:
Also don’t forget you’ll probably need to eager load your models beforehand (
Rails.application.eager_load!
), otherwise they won’t be found as descentendants ofActiveRecord::Base
when that code runsIt’s not that it should be non-queryable, but rather it should be coerced into text.
I think I found a way of hacking the search function to work with JSONB fields. It casts the entire JSONB field as text, which means your search will also include key names.
Hope this helps! Maybe someone else can figure out how to eliminate the key names? And maybe this could also serve as the foundation for a more general solution that can be integrated into the core project?
Edit: I don’t mean to pass the buck on this. I’ve just spent half a day trying to figure this out and I’m zonked right now.
This seems to prevent an error, but even when I put in a valid JSON value to query by, the query by doesn’t actually search the JSON field (it just returns no records), or if I filter specifically by the JSON field (an array in my case), it returns all records, regardless of a match.
@MatthiasRMS solution worked for us with small tweaks:
@jtoy I ended up making those json attrs non-queryable. Give this a try:
None of the above worked for me. This fixed it:
@MatthiasRMS Did you eager load your models beforehand as @fny suggested?
this works, thank you!
Until this is fixed you could use this workaround in your configuration: