4

I'm trying to use the JSON (Postgres 9.3, so not JSONB) field type in my Rails 3.2 application.

I've created the field with the following migration without a problem:

def change
  add_column :blocks, :meta, :json
end

However, when I'm trying to modify the field like this:

b.meta = {name: "John"}
b.save

I'm getting the following error:

ActiveRecord::StatementInvalid: PGError: ERROR:  invalid input syntax for type json
LINE 1: UPDATE "blocks" SET "meta" = '---

I'm not even sure if JSON type is supported in Rails 3.2 but I've seen some posts talking about it as possible (though no details on how it works).

1 Answer 1

7

I think that you're correct that ActiveRecord in Rails 3 doesn't natively support JSON. The cause of your error is that given a complex data type (in this case a Hash), ActiveRecord will first serialize it to a string, and the default serialization is YAML. That's what the --- in your error message is from—it's the YAML header.

A quick solution is to convert the Hash to JSON before assigning it to your attribute:

hsh = { name: "John" }
b.meta = hsh.to_json
b.save

This will get tedious fast, though. Instead, you can tell ActiveRecord to use JSON instead of YAML when serializing this attribute:

class Block < ActiveRecord::Base
  serialize :meta, JSON
end
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I opted for the second solution. How does that effect the performance? Is there any significant downside in this option vs. the integrated support for JSON type that comes with ActiveRecord 4.2 (ignoring all the other differences of course)?
For simple objects I don't think you'll see much performance impact, if any. For large, deeply-nested objects, you might, but it's hard to say. As is always the answer to questions of performance: If you really need to know, profile it. I don't know how ActiveRecord 4.2's JSON support compares. It seems like performance should be pretty similar, but AR 4.2 might do some caching or other optimizations I don't know about.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.