Post-virtus models using Dry::{Struct,Types}

Hey there,

I’ve been using virtus for writing models that are populated by consuming an JSON API in the past and it’s been quite a good experience. As its README states, dry-types, dry-struct and dry-validation “should be considered as virtus’ successors, with better separation of concerns and better features”.

I’m giving Dry::Struct and Dry::Types a shot right now and I’m a bit baffled that Dry::Struct doesn’t include attribute setters. I already read that a Dry::Struct should be treated as immutable and that it is not designed to have its state mutated over time (

What’s your opinion on that, considering that virtus indeed has attribute setters?

I have to admin that I’m used to Active Record and its all-in-one-approach, so virtus having attribute setters is kind of familiar. Let’s say I’d want to write an JSON API client, when having to update a model, how would you do it? Always use the repository pattern, provide the new attributes as a hash and work with the result like this?

project_repository =
project = project_repository.find(42)
updated_project = project_repository.update(, {name: 'A New Name'})

Would love to read your thoughts!

Best regards, Tobias


Well, yes, I don’t mutate values in Ruby and use ROM for persistence like you showed. Since version 0.3 dry-struct has a shortcut for building new structs based on existing ones, it called … new, you can use it like this 'A New Name') #=> struct with a new :name value


so having immutable objects here is a rather personal preference, right? I can live with that, thanks for the input!

About the new method: Yeah, I saw it while digging the library’s code, good to know!

Well, yes. But we build the stack that can operate without mutability at all.