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..