This blog is part of our Rails 5 series.

validates_acceptance_of is a good validation tool for asking users to accept “terms of service” or similar items.

Before Rails 5, the only acceptable value for a validates_acceptance_of validation was 1.

class User < ActiveRecord::Base
  validates_acceptance_of :terms_of_service
end

> user = User.new(terms_of_service: "1")
> user.valid?
#=> true

Having acceptable value of 1 does cause some ambiguity because general purpose of acceptance validation is for attributes that hold boolean values.

So in order to have true as acceptance value we had to pass accept option to validates_acceptance_of as shown below.

class User < ActiveRecord::Base
  validates_acceptance_of :terms_of_service, accept: true
end

> user = User.new(terms_of_service: true)
> user.valid?
#=> true

> user.terms_of_service = '1'
> user.valid?
#=> false

Now this comes with the cost that 1 is no longer an acceptable value.

In Rails 5, we have true as a default value for acceptance along with the already existing acceptable value of 1.

In Rails 5 the previous example would look like as shown below.

class User < ActiveRecord::Base
  validates_acceptance_of :terms_of_service
end

> user = User.new(terms_of_service: true)
> user.valid?
#=> true

> user.terms_of_service = '1'
> user.valid?
#=> true

Rails 5 allows user to have custom set of acceptable values

In Rails 5, :accept option of validates_acceptance_of method supports an array of values unlike a single value that we had before.

So in our example if we are to validate our terms_of_service attribute with any of true, "y", "yes" we could have our validation as follows.

class User < ActiveRecord::Base
  validates_acceptance_of :terms_of_service, accept: [true, "y", "yes"]
end

> user = User.new(terms_of_service: true)
> user.valid?
#=> true

> user.terms_of_service = 'y'
> user.valid?
#=> true

> user.terms_of_service = 'yes'
> user.valid?
#=> true