tl;dr I am searching for an elegant way to perform updates (modify attribute values) in an object graph of structs (nested Dry::Struct
objects).
Context
In a Rails application, I am trying to establish a domain layer, inspired by Domain-driven design, where the business logic shall live. That layer shall be free of ActiveRecord (it is oblivious of persistence) and ActiveModel. I chose to build that layer with dry-struct. I like that it proposes to work with immutable objects in a funtional style.
Problem
If you know DDD, you know the basic building blocks like Aggregate, Entity or Value object. While a value object is exactly about immutability, where dry-struct is a perfect fit, an entity or an aggregate are objects with a life cycle. From a conceptual point of view, such objects can change their attribute values throughout their life cycle, while they carry out business logic. This does not immediately fit well with the immutable nature of dry-struct objects.
Question
I am wondering what is the best and most elegant way to perform updates, that means to change the attribute values, of a dry-struct in a possibly deep object graph of structs (like an aggregate). I know that Dry::Struct
offers #new as instance method to create a copy with overriden attribute values. But to change a nested struct, I have to chain these #new
calls from the toplevel struct (aggregate root) down to the nested struct that I want to change.
Is there a more elegant way to do this? For example Elixir as a functional language has immutable basic data types and really good support in the standard library, like the Kernel.update_in/3 function that solves exactly my use case. Does the dry-rb ecosystem offer something similar?