One of the processes that Ruby on Rails makes very easy is validating models conditionally. The perfect example I have encountered is validating parts of a model during updates, e.g. updating a user's password. We want to allow the users to enter the current password first, then enter a new password.
Let's write a failing test first:
# test/models/user_test.rb
class UserTest < ActiveSupport::TestCase
test "current_password throws an error when entered incorrectly" do
user = User.new(current_password_required: true, current_password: '')
assert !user.valid?
assert_equal ["Current password can't be blank"], user.errors.full_messages
end
end
If we run the test now, in Rails 5 we can us the handy rails command, which makes running single tests much easier:
bin/rails test test/models/user_test.rb
we get an ActiveModel::UnknownAttributeError exception about the unknown attributes, currentpasswordrequired, and current_password.
Let's add them to our User model:
class User < ActiveRecord::Base
attr_accessor :current_password, :current_password_required
validates :current_password, :presence => true, :if => :current_password_required
end
If we run the test now, we can see that it passes. Let's write the opposite test and see it pass:
# test/models/user_test.rb
test "current_password is ok when entered correctly" do
assert user.valid?
end
We can then add other validations about checking that the password entered is the same as the current password, etc..
Happy coding!