-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Updates to validation and coercion: Fix #211 and force order of operations for presence and coercion. #212
Conversation
…ional and not present Updated validator to only run custom optional validation when the param is present. Re-wrote validations_spec to be a little more robust. Added section to documentation for custom validation.
Don't pull this yet. Just realized that this bug also exists when you set |
Spent a little more time looking into that bug and I don't believe its an issue. This pull request is ready for review and pull. |
Scratch that, I just resurfaced the bug. It seems that coercion isn't guarantee to happen before the validators run. If this is the case the validators could be working with incorrect types. I'm updating the code now to run coercion tests first. |
Param validation will check for presence first and then handle any coercion. This fixes a bug where coercsion happens after the fact and validation icorrectly fails or passes
…cases Minor style changes and an update to the describe block
@dblock I'm done with all the changes here. Please review. @schmurfy you should take a look as well and make sure I didn't break anything obvious. I was also playing a bit with the custom coercion classes. Do you think those should be validated as well? For example, I wrote the following tests expecting them to pass, but they didn't. After further investigation I realized it wasn't supported and outside the scope of the changes I was making. What do you think? module CoerceValidatorSpec
class User
include Virtus
attribute :id, Integer
attribute :name, String
end
end
it 'validates a custom coercion' do
subject.params { requires :user, :type => CoerceValidatorSpec::User }
subject.get '/user' do 'complex works'; end
# Expected it to throw a 400 but throws a 200
get '/user', :user => { :not_there => '32' }
last_response.status.should == 400
last_response.body.should == 'invalid parameter: user'
# Should't complex object types validate types?
Not sure what the response would be here? Invalid user->id?
get '/user', :user => { :id => 'not and int', :name => 'Bob' }
last_response.status.should == 400
end |
I did not see any breaking change, good patch :) Validating a sub object like your example works but only partially, from what I remember your first test should succeed, the coercion should fails if the hash does not include any of the object attributes. |
```ruby | ||
params do | ||
requires :name, :doit => true | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit of a contrived example. It would be nice to find something more "useful".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take a shot at updated the whole section and improving my example. I've learned a lot of things that you can do that we haven't documented.
I am going to merge this, thank you. My comments are minor, feel free to make pulls to improve those! |
Updates to validation and coercion: Fix #211 and force order of operations for presence and coercion.
@@ -106,15 +109,31 @@ def validates(attrs, validations) | |||
|
|||
@api.document_attribute(attrs, doc_attrs) | |||
|
|||
# Validate for presence before any other validators | |||
if validations.has_key?(:presence) && validations[:presence] | |||
validate('presence', validations[:presence], attrs, doc_attrs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just realized that I need to remove presence from the validation array. Shouldn't affect it negatively. Would just cause it to validate twice. I'll fix that with the next batch of updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your hard work, Adam.
Will make the documentation updated discussed here after #221 gets finalized and merged. |
@adamgotterer I did some tests on validating sub objects and the case which is working (by returning 400) is passing an empty hash but otherwise you are right we cannot really implement this only with Virtus. But there is hope ;) params do
requires 'user.id', :type => Integer
requires 'user.login', :type => String
end All the work I did on grape was inspired by what I did on goliath, since goliath now longer suits my needs due to recent changes I turned to grape which was the closest match (I was really surprised that really no frameworks suitable for writing quick REST services already exists with inputs validation). params do
requires :user, type: User
end I may have time to give it a try this week end. |
Here we go: #222 |
This pull request turned into something slightly larger then originally planned. While fixing this bug a few other bugs and improvements popped up that were addressed as well.