Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Dry::Struct instead of Virtus #59

Merged
merged 6 commits into from
May 24, 2017
Merged

Use Dry::Struct instead of Virtus #59

merged 6 commits into from
May 24, 2017

Conversation

tpendragon
Copy link
Collaborator

This isn't a totally faithful conversion - effectively it implements writers where Dry::Struct doesn't want writers. There's some other weirdness in here around the fact that the newer versions of Dry::Struct won't cast parameters that you don't pass in the initializer.

@tpendragon
Copy link
Collaborator Author

So there was a significant difference in behavior between 0.2 and 0.3 of dry-struct. Further, the master branch doesn't work at all (some bug with features they're adding regarding inheritance.) So I have some concern about the stability of that project - but it DOES have a maintainer. This only took a day to do, and there were backwards compatible steps in the middle.

Thoughts on if we should actually go through with this?

@tpendragon
Copy link
Collaborator Author

One thing I want to note - I do like the Dry::Types coercion a lot better than the ones in Virtus, and we can share them with Reform.

@bmquinn
Copy link
Member

bmquinn commented May 23, 2017

Still digging into the code a bit, but I found a fairly concise comparison between dry-struct and Virtus at http://dry-rb.org/gems/dry-struct/

dry-struct look somewhat similar to Virtus but there are few significant differences:

  • Structs don’t provide attribute writers and are meant to be used as “data objects” exclusively
  • Handling of attribute values is provided by standalone type objects from dry-types, which gives you way more powerful features
  • Handling of attribute hashes is provided by standalone hash schemas from dry-types, which means there are different types of constructors in dry-struct
  • Structs are not designed as swiss-army knifes, specific constructor types are used depending on the use case
  • Struct classes quack like dry-types, which means you can use them in hash schemas, as array members or sum them

@tpendragon
Copy link
Collaborator Author

Yup, that's a good summary. This PR relates as such:

Structs don’t provide attribute writers and are meant to be used as “data objects” exclusively

This PR adds writers.

Handling of attribute values is provided by standalone type objects from dry-types, which gives you way more powerful features

👍 This PR uses those.

Handling of attribute hashes is provided by standalone hash schemas from dry-types, which means there are different types of constructors in dry-struct

Yes - in 0.2 the "schema" constructor worked exactly the way I wanted. In 0.3 I had to overwrite the new method to get default values instantiated even if you didn't pass a property to the hash (so Book.new.title would return [] instead of nil).

Structs are not designed as swiss-army knifes, specific constructor types are used depending on the use case

👍 This seems fine, but it just so happens what's most useful to us is the schema constructor type, which works similarly to Virtus'.

Struct classes quack like dry-types, which means you can use them in hash schemas, as array members or sum them

Right now this is pretty useless to us - I'm doing everything I can to avoid nested objects.

@tpendragon
Copy link
Collaborator Author

tpendragon commented May 23, 2017

I should mention that I had a version of the writers which were immutable - you'd get a new instance of Book when you set a property (dry-struct 0.3 provides #new on instances to enable this). It worked fine, but I wasn't sure the community was ready for the weirdness that happens from that.

@tpendragon
Copy link
Collaborator Author

The issues I ran into between versions are documented here: dry-rb/dry-types#198

@tpendragon
Copy link
Collaborator Author

I was able to get rid of the #new hack by using defaults as they were meant to be in dry-types. I'm for this change now.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling b0e07f3 on try_dry_struct into aeee73b on master.

@@ -2,13 +2,13 @@
module Valkyrie::Persistence::Fedora
class DynamicKlass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in scope for this PR, but I'd prefer DynamicClass here -- only using klass or clazz where it would conflict.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#61 created.

Copy link
Contributor

@botimer botimer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. A couple of stylistic/semantic comments, but no objection to merging.

@@ -4,6 +4,12 @@ module Types
include Dry::Types.module
ID = Dry::Types::Definition
.new(Valkyrie::ID)
.constructor { |input| ::Valkyrie::ID.new(input) }
.constructor do |input|
Valkyrie::ID.new(input)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This indentation tripped me.

base.include Virtus.model
base.include Draper::Decoratable
base.extend ClassMethods
class Model < Dry::Struct
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filename / classname mismatch. Consider model.rb?

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 0e1b9b6 on try_dry_struct into aeee73b on master.

@botimer botimer merged commit bba1204 into master May 24, 2017
@tpendragon tpendragon deleted the try_dry_struct branch May 24, 2017 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants