-
-
Save ernie/33f75f2294885b9806f9 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby | |
gem 'activerecord' | |
gem 'minitest' | |
require 'active_record' | |
require 'minitest/autorun' | |
ActiveRecord::Base.establish_connection( | |
adapter: 'postgresql', | |
database: 'playground' | |
) | |
ActiveRecord::Schema.define do | |
create_table :items, :force => true do |t| | |
t.jsonb :data, null: false, default: '[]' | |
end | |
end | |
class Item < ActiveRecord::Base | |
serialize :data, JSON | |
end | |
class SerializationTest < Minitest::Test | |
def item | |
@item ||= Item.new | |
end | |
def test_item_serializes | |
assert_equal [], item.data | |
end | |
end | |
# TypeError: no implicit conversion of Array into String |
https://gist.github.com/ernie/33f75f2294885b9806f9#file-serialization-rb-L15 This shouldn't be a string, you should give it a valid ruby value.
https://gist.github.com/ernie/33f75f2294885b9806f9#file-serialization-rb-L20 You don't need this.
Yeah, the semantics of the old serialize
macro are really wonky. The rough plan is to soft deprecate it for complex cases in favor of the attributes API. In the case, you don't need to use serialize
at all though, the attributes type handles it properly.
For those who might see this later: I know I don't need serialize
in this simple case. In the real case, I'm serializing/deserializing to an object in my domain model. It's probably worth noting to folks that they will get the deserialized hash/array in their load method if their column type is json/jsonb.
It makes sense, if you think in terms of what the adapter delivers being the "serialized" data, but it's not entirely intuitive, either.
So, the nice thing is that without using the
serialize
macro, we get deserialized data from the adapter. The bad thing is that this breaks typical serialize behavior in that the data isn't known to be deserialized yet, so it gets passed to the load method of a defined serializer, if we use one. Easy enough to work around, but definitely unexpected.