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

Is there a way to programatically figure out which predicate failed? #43

Closed
greyblake opened this issue Jan 5, 2016 · 8 comments
Closed

Comments

@greyblake
Copy link

Hi!
First of all, thanks for the great gem! I hope AciverRecord will die one day(it's dying hard...).

I'd like to know, s there a way to programatically figure out which predicate failed?
Result of validation looks like this:

{ :email => ["email must be filled"] }

Basically, it's the same of ActiveModel::Errors#messages returns: attribute and human readable messages.

The use case where it is not enough: http API, where every type of validation error may result into different code.
I am developing JSON API, and it would be greate to give to API consumers ability to distinguish between different validation failure, because they may want to handle it in different way.

In general, result in such format would be enough:

{ 
  :email => {
    :filled => "email must be filled"
  }
}

Thanks!

@solnic
Copy link
Member

solnic commented Jan 5, 2016

Not sure if I want to kill anything with my projects but I'd be happy to see people using this gem instead of AR's validations ;)

Anyhow, you have access to all violated rules via schema.(input).failures. Let me know if that works for you.

@greyblake
Copy link
Author

Thanks for the quick reply!)

Ah, sorry, I've mislookeed, that there was .messages call at the end in the example.
So, yes, it works as I wanted it to be! It returns result, as vanguard does :)

Here is just example, if somebody will have the same issue:

require 'dry-validation'

class Schema < Dry::Validation::Schema
  key(:email) { |email| email.filled? }

  key(:age) do |age|
    age.int? & age.gt?(18)
  end
end

schema = Schema.new
result = schema.call(email: '', age: 19) # without .messages

p result
# => #<Dry::Validation::Schema::Result params={:email=>"", :age=>19} messages={:email=>[["email must be filled"], ""]}>

p result
[#<Dry::Validation::Rule::Result::Value success?=false input="" rule=#<Dry::Validation::Rule::Value name=:email predicate=#<Dry::Validation::Predicate id=:filled?>>>

P.S.
Unfortunately I don't use the gem yet, but I want to give it a try! The idea is really brialiant.
Thanks!

@waiting-for-dev
Copy link
Member

If I'm not wrong, currently the way to access given predicate for an error is:

error = schema.call(input).errors.first
puts error.result.rule.predicate.id

So it is possible to reach to it, but I'm not sure if along the way our old pal Demeter would survive to a heart attack :D

But more than about judge Demeter health I'm worried about relating predicates with error messages, because, as far as I have deduced, there is no straight way.

Now, the output of result.messages is:

{ attribute: [message_1, message_2] }

Would you consider changing it to:

{ attribute: { predicate_1 => message_1, predicate_2 => message_2 } }

If so, with some time, I could try a pull request if it is not trivial for one of the maintainers.

@solnic
Copy link
Member

solnic commented May 18, 2016

Current messages structure is optimized for displaying error messages in the UI, including predicates there would complicate things. We can introduce another error message structure for cases where people need to know which predicate failed.

@waiting-for-dev
Copy link
Member

And what about introducing a way of getting the error message from a Dry::Validation::Error instance? That way one could iterate over the array of errors and for each one get its predicate and its message, building the JSON response structure as needed. What do you think about it?

@solnic
Copy link
Member

solnic commented May 18, 2016

We already have an API for that, it's ErrorCompiler, you can create your own and that's all. Validation::Error is sort-of private

@waiting-for-dev
Copy link
Member

waiting-for-dev commented May 18, 2016 via email

@solnic
Copy link
Member

solnic commented May 18, 2016

no worries, it's not even documented yet

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

No branches or pull requests

3 participants