Closed maxd closed 4 years ago
No such API yet. I'm marking this as a feature request.
What about nested hashes? Have you thought about the structure of the object that would provide this kind of information?
Maybe:
attributes = ParamsValidator.attributes
a = attributes.first
a.name # :a
a.optional? # false
a.required? # true
This could be a done a separate extension. Converting rule ast into such object won't be a problem. I don't need this though, at least not now, so I won't be working on it. I'll mark this as help-wanted for now.
I'm in need of this functionality. In looking at the code it seems like creating a attributes-compiler that walks the ast, similar to the hints-compiler is a good place to start? @solnic is that a reasonable way to start working on this feature?
@rx yes we could do it like that although I wonder now if that wouldn't be an overkill. Maybe it's better/simpler to mark rules with additional meta-data in the DSL, then you could simple look at Schema.rules
and inspect it (this returns a hash with Symbol
=> Schema::Rule
mapping).
@solnic, @backus Here is a WIP version. https://github.com/voomify/dry-metadata
Notes: (In no particular order.)
fields.each do |field|
puts field.name # the name of the field
puts field.required? # if the field is required
puts field.optional? # if the field is !required
puts field.types # the array of valid types
puts field.logic # polish notation of the logic (minus custom rules)
puts field.fields # nested fields or []
end
# To fetch all required fields:
fields.required_fields
# To fetch all optional fields:
fields.optional_fields
# To fetch a single field by name:
fields[:age]
# To sort by name:
fields.sort
# To get an array of hash representations suitable to serialize:
fields.to_a
require 'dry-validation'
UserSchema = Dry::Validation.Schema do
required(:name).filled
required(:age).maybe(:int?)
required(:address).schema do
required(:street).filled
required(:city).filled
optional(:zipcode).filled
end
end
fields = Dry::Metadata::Fields.from_validation(UserSchema)
This is experimental - not all cases have been spec'ed yet. Please report any issues you find.
require 'dry-struct'
module Types
include Dry::Types.module
end
class Address < Dry::Types::Struct
attribute :street, Types::Strict::String
attribute :city, Types::Strict::String
attribute :zipcode, Types::Strict::String.optional
end
class UserStruct < Dry::Types::Struct
attribute :name, Types::Strict::String
attribute :age, Types::Strict::Int
attribute :address, Address
end
fields = Dry::Metadata::Fields.from_struct(UserStruct)
Updated to work with new dry-l, dry-v ast. This branch is pulling dry-v and dry-s from master.
https://github.com/voomify/dry-metadata/commit/bcdfe967b6c05b418ee4c29778c58a0a414bd5be
@rx is this still used/maintained ? I did some ast visitor for my dry-validation and wonder if it is worth using your gem ?
@mkristian
@rx I am certainly interested! We wrote some code to convert dry-v forms into JSON Schema (to generate Swagger data—very nifty!) but it's very hacky and ad hoc.
have to add my 2 cents: we also wrote a piece of code to convert dry-v to swagger json and that is where my interest in this 'gem' comes from ;)
This type of conversions are highly desired, and it's one of the reasons why dry-v uses formal AST to represent rules. This is not yet 1st-class but will be once we finally get to 1.0.0. Just remember we're still in beta phase, so AST structure may change. FWIW I don't expect to see any serious breaking changes, but we may tweak it a little bit before 1.0.0.
@mkristian Interesting! Here's our very primitive and inflexible solution if you're interested: https://gist.github.com/felixyz/62130f9f6b9aa309c3ddfb9fd534a0fc
I will look into replacing most of it with dry-metadata
or something similar next time we need to touch this code.
@solnic Looking forward to stronger support and makes sense to do that post-1.0 👍
@felixyz thanks for the gist. next time I need to touch our AST visitor I will come back to it. right now things are working for me but always looking for more general and robust solutions in the long run.
Hi,
For example I have schema:
How can I get list of required fields ([:a]), optional fields ([:b]) and all fields ([:a, :b])?
FYI: I want to use these lists in unit-tests for check validation of optional fields.