-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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
ActiveRecord/ActiveModel '#validate' alias for 'valid?' #14456
Conversation
While I understand that it reads nicer in certain less common cases, but I'm not sure if the benefits are worth it. The reason I'm on the cautious side is because every method we add to the Active Record API increases comes with the risk of conflict with user code. If we add this method, you will no longer be able to have db columns called While I agree the former is quite unlikely, I think it is quite possible that we will cause problems for existing apps/gems that defines a For example, some apps might have defined This is not a particular high risk name for us to use, but the benefits seems pretty insignificant either. Personally I'd err on the cautious side, but I'll defer to @dhh to weigh the pros/cons. |
I don't think it's a problem to add this as an alias because it happens to the base class. So if you have your own validate method, you'll just be overwriting the method. As long as we are not using the method internally.
|
assert_empty r.errors[:author_name] | ||
|
||
r.validate(:special_case) | ||
refute_empty r.errors[:author_name] |
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.
There's assert_not_empty
I guess you could use, we try to avoid refute
usage.
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.
Excellent; I like that better. Pushing a test cleanup.
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.
Actually, I'm starting to have second thoughts if the only use case we can think for this is tests. These tests would have been just as well if you had a assert_not r.valid? before your error check. Do you have a non-test example?
On Mar 23, 2014, at 16:45, Henrik Nyh [email protected] wrote:
In activerecord/test/cases/validations_test.rb:
@@ -52,6 +52,21 @@ def test_error_on_given_context
assert r.save(:context => :special_case)
end
- def test_validate
- r = WrongReply.new(:title => "Valid title")
- r.validate
- assert_empty r.errors[:author_name]
- r.validate(:special_case)
- refute_empty r.errors[:author_name]
Excellent; I like that better. Pushing a test cleanup.—
Reply to this email directly or view it on GitHub.
Just as a side note, thinking about your example, in general I add an assertion to the |
I got a comment by email (that I don't see on this pull request for some reason) – whether I have more use cases than testing validations per above. Grepping through one of our apps for uses of I see some non-test code that collects errors on several records by calling There's also some non-test code where one controller (as part of an unconventional flow) is passed a set of attributes and shows a form – it validates to show errors, if any, but doesn't do anything conditionally based on the validation result. I also see several cases of testing validation callbacks: Examples aside, I think a method like this makes a lot of sense in the API. I know I've wanted this method several times in the past. |
I too dislike having to call As a side issue, I don't usually use def assert_valid(model)
model.valid?
assert model.errors.to_a == [], "Unexpected errors: #{model.errors.to_a}"
end I also have: def refute_valid(model)
model.valid?
refute model.errors.to_a == [], "Expected errors but found none"
end
def assert_errors(messages, model)
model.valid?
assert model.errors.to_a.sort == messages.sort, "Expected: #{messages.sort.inspect}\nActual: #{model.errors.to_a.sort.inspect}"
end
def assert_includes_error(message, model)
model.valid?
assert model.errors.to_a.include?(message), "Expected #{model.errors.to_a.inspect} to include #{message}"
end All of them would be improved by using |
Aight, I buy the collection case. On Mar 23, 2014, at 7:59 PM, Henrik Nyh [email protected] wrote:
|
Let me know if there's anything else I can do towards getting this merged. |
Semantically it would seem to me that |
I implemented something along those lines first, but I figured it might be better to do something minimal. Also consider that e.g. 'save' returns a bool, so the current behavior has precedents. Sent from my iPhone
|
Could you add a CHANGELOG entry? |
And also please squash your commits |
Will do! squash and then force push this branch, right? Sent from my iPhone
|
Right |
It's unintuitive to call '#valid?' when you want to run validations but don't care about the return value. The alias in ActiveRecord isn't strictly necessary (the ActiveModel alias is still in effect), but it clarifies.
Added CHANGELOG entry, rebased against upstream master, squashed. The ActiveModel CHANGELOG just says "Please check 4-1-stable for previous changes." so I'm not sure what to do there. Left it alone until I hear differently. |
ActiveRecord/ActiveModel '#validate' alias for 'valid?'
Merged. Thank you so much |
@rafaelfranca Thanks so much for the feedback and for merging! |
It would be so cool if this method would return |
@bogdan What would you use it for? |
I've written about it here: #8639 In this case method could look like this: def build_user
user = User.new
# additional manipulations
user.validate
end |
Aha, I think I understand. We probably shouldn't continue this discussion here (since the pullreq is merged and notifications may go out to commenters), but I suggest making your own pull request and/or starting a discussion on the rubyonrails-core mailing list. Then post the link here for interested parties. |
It's unintuitive to call '#valid?' when you want to run validations but don't care about the return value, e.g. in a test:
Compare that to
The alias in ActiveRecord isn't strictly necessary (the ActiveModel alias is still in effect), but it clarifies.
@dhh was positive when I asked a few months ago: https://twitter.com/henrik/status/390205394305703936
An alternative implementation would be to actually implement
valid?
in terms ofvalidate
, but I figured an alias would be the simplest thing that works.