A Ruby on Rails serialiser that can read and write ActiveRecord models (or any other GlobalID) to your serialised fields.
Rails serialisation uses the GlobalIdSerialiser#dump and GlobalIdSerialiser#load methods - which convert your data to and from JSON.
However, internally, these methods use GlobalIdSerialiser#marshal and GlobalIdSerialiser#unmarshal. These do the conversion from GlobalID to model and back again, without the conversion to JSON. So you can use these anywhere that expects standard ruby objects.
@alice = Person.create name: "Alice"
@data = { title: "Welcome to my blog", author: @alice }
@marshalled_data = GlobalIdSerialiser.marshal @data
puts @marshalled_data # => { title: "Welcome to my blog", author: "gid://my_app/person/1" }
@unmarshalled_data = GlobalIdSerialiser.unmarshal @marshalled_data
puts @unmarshalled_data # => { title: "Welcome to my blog", author: Person<id: 1, name: "Alice"> }Create your ActiveRecord model, declaring your serialised field - but instead of declaring the coder as JSON, use GlobalIdSerialiser.
class BlogPost < ApplicationRecord
serialize :data, coder: GlobalIdSerialiser, type: Hash
endThen go about your day, safely storing your models in your serialised field.
@alice = Person.create name: "Alice"
@blog_post = BlogPost.create data: { title: "Welcome to my blog", author: @alice }
puts @blog_post.data_before_type_cast # => '{"title":"Welcome to my blog","author":"gid://my_app/person/1"}'
@reloaded_blog_post = BlogPost.find @blog_post.id
puts @blog_post.data["author"] # => Person<id: 1, name: "Alice">When your data is marshalled, any objects that implement GlobalID::Identification get converted to a GlobalID URI string.
Later, when that data is unmarshalled, any GlobalID URIs are passed to the GlobalID::Locator to find them in the database. If the record in question has been deleted, the data will be unmarshalled as nil. This is so as much of the data as possible is retrieved without raising any ActiveRecord::RecordNotFound errors (which would stop the unmarshalling process part-way through and leave you with no data at all).
So be aware that nils may be returned if the record in question has been deleted.
Add it to your Gemfile. bundle install. Relax.
This is licensed under the LGPL. This may or may not make it suitable for your needs.