Adding the ability to "reuse" schema information in dry-initializer

Hey, there. Let me briefly talk about why I am using dry-initializer over dry-struct, first, before launching into what I am proposing.

I’ve stumbled upon these libraries two days ago, and I’m already really enjoying the prospect of dumping activemodel and all of my associated custom metaprogramming for the dry-rb family. I’ve already built up a few POCs to prove these libraries’ worth to myself and eventually my team.

I ended up adding lazily evaluated default values to activemodel, with some metaprogramming. I get this out of the box in with dry-initializer - and because you use instance_exec like I was doing myself, I can refer to other fields in my model. Great.

Really, my issue now is, I would like to avoid repeating myself when I start using dry-validation, and try to base my contracts on the same initial schemas for my objects - which seems like it would have been simple enough had I been using dry-struct. But, not with dry-initializer.

I would like to avoid writing to additional DSL wrappers for dry-initializer to “synthesize” and record my object’s schema to build upon for later dry-validation usage, but that seems like it is my smartest option.

My question is:

Have we thought about adding an “extension” to dry-initializer that would record the compatible portions of param and option arguments as a schema? Even just the names and types? It seems like it would be very easy to do. And it would make for better interoperability with dry-initializer.

Side note, I really like your support for the arity==2 type procs in dry-initializer. Very handy for automatically setting references to a parent model.

Hey!

I started working on dry-rails recently and this is the place where we can add proper ActiveModel/ActionView support. I’d much rather do it there then to expand functionality of dry-initializer because it is already a complex library and it sits in the very core of other libraries, including rom-rb.

When it comes to structs, schemas and validation what’s recommended is to define validation schemas (either using dry-schema or dry-validation, depends on what you need) and then infer structs from it. Doing it the other way around (which I know lots of people want to do because it feels more natural, but it’s…wrong :slight_smile:) is problematic because there’s no direct translation that can be applied in all of the possible cases, whereas with schema => struct you can translate that :100: % with no limitations.

There are a couple of missing parts now:

  1. no dry-schema => dry-struct conversion API - this can be implemented easily, we already implemented generating dry-struct from rom-rb’s database schemas and we know it’s a simple thing to do
  2. no support for setting default values - this needs some discussions. Maybe it makes sense to have it as a dry-schema extension. Some quick PoCs should give us answers.

To answer your question:

Have we thought about adding an “extension” to dry-initializer that would record the compatible portions of param and option arguments as a schema? Even just the names and types?

No, because, like I mentioned, it is not recommended to generate validation schemas from structs and dry-initializer is already complex enough. We encourage the exact opposite because structs are meant to represent valid data all of the time.

Let me know what you think. We can add support for default values and generating structs from schemas to main dry-rb libraries and then implement rails-specific bits in dry-rails. I think a lot of people could benefit from such an effort and it’s not a difficult thing to do :slightly_smiling_face:

I think it makes perfect sense to have default value support in dry-struct, if that’s what you mean. I only was using dry-initializer because of that capability.

Also, for this particular project I have no need for rails - it’s not a web application and not a microservice.

I am happy to help out with any of the coding, as long as you are fine with the fact that I am not familiar enough with your team’s coding style to promise that it would “smell” right to you. :wink:

Well, actually, the other capability that I wanted was “setter” methods.

No, I meant that we don’t have any specific idea about setting default values during the data validation process. dry-struct supports default values btw - it’s just an attribute with a default type set.

This won’t be added. We have functional approach in dry-rb world - there are no public APIs provided to mutate data and that’s intentional.

Understood on the functional approach.

The dry-struct default value is not something that I can use for this use case - because I need to have access to instance methods via instance_exec.