How to serialize hstore for Rails model


I have been using Virtus, and in the documentation of this project it says this gem dry-types can be a replacement of the Virtus gem, I’m using it to serialize/parse my hstore column in this way: (Using the Virtus gem)

Today I have tried to replace the Virtus implementation with the dry-types gem without success, could you please write an example of how to accomplish this with dry-types?


@victorhazbun Can you share with us what you tried (code examples are great), and how it specifically fell short of what you wanted to achieve?


I’ll continue this thread because I’m trying to do the same thing.

Say I have a user model with a hstore column:

class User < ApplicationRecord
  serialize :meta, Options

With a Meta virtus class that looks like:

class Meta
  include Virtus.model

  attribute :badge_number, Integer    
  attribute :reminders_enabled, Boolean, default: false
  attribute :nickname, String

  def self.dump(meta)

  def self.load(meta

If the hstore content of meta is "nickname"=>"awesome", "badge_number"=>"12", "reminders_enabled"=>"true", virtus will properly coerce the values in the Preferences::User class and I can do things such as user.meta.badge_number = 1; and Rails/virtus does all of the right things and updates the backing hstore column.

How do I implement such functionality with dry types?

I’ve tried

module Types
  include Dry::Types.module

class Meta < Dry::Struct
  constructor_type :schema

  attribute :badge_number, Types::Int
  attribute :reminders_enabled, Types::Bool
  attribute :nickname, String

  def self.dump(meta)

  def self.load(meta)

but all of the attributes in meta are then nil.

If I try with the permissive constructor type, I get Dry::Struct::Error ([] :badge_number is missing in Hash input).

I use this pattern of a hstore meta or options or some column, serialized with Virtus all over my app, it’s been super useful. I feel like I’m missing something obvious here, so would appreciate any help you all can offer.



I believe constructor_type :symbolized should work in your case.


When attempting to use constructor_type :symbolized, I get the error:

.../.bundle/gems/dry-core-0.4.5/lib/dry/core/class_attributes.rb:65:in `block (3 levels) in defines': 
Value :symbolized is invalid for class attribute :constructor_type (Dry::Core::InvalidClassAttributeValue)

This is with dry-struct 0.4.0 and dry-types 0.12.2.


It seems like that they aren’t supported anymore? I see a note in that commit on using dry-validation, but the note was removed in the commit so not sure what the recommended strategy is here.