Rails: How to work with serialize attributes and Sorbet

200 Views Asked by At

I can't find any examples of how to deal with attributes that are serialized columns.

class MyClass < ApplicationRecord
  serialize :related_pages, Array
end

In this case, it is an Array of String (eg T::Array[String]).

The only solution I have found is to cast it: T.cast(related_pages, T::Array[String])

Is this the best solution?

1

There are 1 best solutions below

0
Brian Hicks On

Unfortunately, I don't think there's a good way to automatically get what you want right now. I'd say to use Tapioca, but it looks like it generates untyped getters and setters for serialize calls, which won't help you. If you feel confident in Tapioca, I suppose you could write your own DSL compiler, but that's its own can of worms.

That said, there is a way to get around this manually that doesn't involve T.cast: you can write your own .rbi files. It has some problems (e.g. you have to keep them in sync yourself, and you're basically asserting to the type checker that you know what you're doing) but it's a possibility!

For yours, I think it'd look like this (I haven't run this; it's just for illustration):

# typed: strict

class MyClass
  extend T::Sig

  sig { returns(T::Array[String]) }
  def related_pages; end

  sig { params(value: T::Array[String]).returns(T::Array[String]) }
  def related_pages=(value); end

  # whatever other helper methods you need like `related_pages_before_last_save` etc
end