Conditional validation with Rails

Let’s say we have a User model that has a unique username, something like this

class User < ActiveRecord::Base
validates :username, uniqueness: true
end
view raw gistfile1.rb hosted with ❤ by GitHub

And let’s say that users can be active or inactive, and we scope our model accordingly.

class User < ActiveRecord::Base
default_scope { where(active: true) }
validates :username, uniqueness: true
end
view raw gistfile1.rb hosted with ❤ by GitHub

Now, imagine that we want usernames to be unique, but only among¬†active users.* In other words, active users can have the same usernames of inactive users. If we have a user with the username “Alice”, and this user is inactive, then our validations should not stop us from creating a new, active user with the username “Alice”.

How do we do this? Simply, we make our uniqueness validation conditional.

validates :username, uniqueness: true, if: lambda { |user| user.active == true }
view raw gistfile1.rb hosted with ❤ by GitHub

* We can think of other real-world scenarios where we might want to do this e.g. expired e-mail addresses, archived articles