Replace ActiveModel in form_for, form_with with dry family

Hi to all. Sorry for short question, it may seem frivolous to you. But i’ve really googled it and didn’t find any confident response or example.

Can I replace ActiveModel with dry-schema, dry-struct, dry-validation in rails constructions with form_for, form_with? Does they suggest such use? Are there any pitfalls?

Anyway I’ll try to dig deeper while waiting an answer :slight_smile:
Thank you

I’ve made it with ActiveModel. But anyway I appreciate your answer if it ever will be given :slight_smile :slight_smile:

Sure, it’s certainly possible to do this. I’ve done it plenty of times with plain Ruby classes, so dry-struct would just be a shortcut for attribute definition and type-checking.

It’s important to understand the conceptual differences between ActiveModel and Dry-Struct. The Dry system is intended to work in a functional way, with immutable structs. The sort of mutation you typically do with activemodel objects is not supported, by design.

That means validation is an entirely separate step that takes place before instantiating the struct objects. You’ll need to stitch the two processes together in some way, which is easy with dry-monads. See also dry-rails for how you would integrate dry-schema into a Rails controller.

If you’re unfamiliar with all of this, I would recommend taking a piece at a time and solving a single problem with it. It will become clear over time how they work together, but in my experience trying to use it all at once is too hard.

The minimum-viable form object would look something like this:

module T
  include Dry::Types(default: :strict)

  Username = Strict::String.constrained(min_size: 3)

class Form < Dry::Struct
  extend ActiveModel::Naming
  include ActiveModel::AttributeMethods

  attribute :username, T::Username

  def persisted?
1 Like