-
Notifications
You must be signed in to change notification settings - Fork 67
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
Validate with conditions #128
base: master
Are you sure you want to change the base?
Conversation
The `:if` options allows to define conditions for validations to be executed just in concrete contexts.
This is really great. Also parallels the way Rails can handle validations. Here are a couple of requests:
By the way, this is failing in Travis. Sometimes Travis needs a refresh to pass. Thanks again! |
Oops! sorry for the failing tests, they go green locally 😓. And agree with you! would be better to get it working with validate :some_column, presence: true, if: -> { some_accessor == my_desired_value } But I'm not sure about how could I access the model attributes implicitly from inside the block. Do you know what I mean? Do you know how can I do it? My use case by the moments works well with what is done in this PR: # app/models/user.rb
class User
include MotionModel::Model
include MotionModel::ArrayModelAdapter
include MotionModel::Validatable
columns :external_id, :email, :password, :password_confirmation
validate :email, presence: true, email: true
validate :password, presence: true, if: :new_user?
validate :password_confirmation, confirmation: true, if: :new_user?
def new_user?
external_id.nil?
end
end # app/screens/signup.rb
# (...)
u = User.new(email: '[email protected]', password: 'secret', password_confirmation: 'secret')
if u.save
# do successful stuff
else
# do failure stuff
end
# (...) |
It looks like you are doing a send for the if validation[:if]
case validation[:if]
when Symbol then return send(validation[:if])
when Proc then return call(validation[:if])
else
raise ArgumentError.new(':if requires a Symbol denoting a method or a Proc/lambda')
end
end
end Note that the validator is an instance method of the model, so you would be able to write code like this: validate :password, if: -> { password.length > 7 && password.match(/[0-9]/ && new_user? }
# or
validate :password, if: :strong_password?
# ...
def strong_password?
# some code to really figure out password strength
end What do you think? Would something like this work? |
You are right, it should work. Let me check it out and I'll come back with some changes 😉 validate :password, strong_password: true, if: :have_to_validate_password? Right? Thx! |
I just used validate :zip, if: -> {
case country
when 'US' return zip.match(/[^0-9]{5}(-[0-9]{4})?/
else return !zip.empty?
end
} Something like that. It's just one other way to write validating code -- moving the method up to the |
Yes, totally agree. |
Sorry @sxross, I was thinking on it and I'm not "totally agree" with you.
And I think that two scopes for the same option is not correct. validate :password, with: -> { password.length > 7 && password.match(/[0-9]/ && new_user? } What do you think? |
d5cedb3
to
5f9d47b
Compare
@sxross Travis is failing again. I don't understand why, all is working fine in my machine. Thx! |
I agree. That makes perfect sense.
|
Please try removing |
5879b0e
to
aa45ed7
Compare
aa45ed7
to
20b82cb
Compare
@sxross I've made it working doing some changes in Travis configuration and gem dependencies. |
I just want to set starting point with conditional validations.
I think it'd be cool to provide some feature to execute validations just in some defined contexts.
In this PR I'm adding the
:if
option as a very silly way to provide this.