Rails 7 introduces only_numeric option within numericality validator


ActiveRecord comprises several pre-defined validation helpers that we can use directly within our class definitions. There are common validation rules that these helpers provide. This means that whenever a validation fails, an error will be added to the object’s errors collection, and this is related to the attribute getting validated.

We also have the liberty to add the same kind of validation to different attributes with a single line of code. This is because every helper accepts an arbitrary number of attribute names.

There are a vast number of helpers and numericality is one of them. This helper ensures that our attributes have only numeric values.

To understand how this validation works, first, we have to generate a table with JSON column(s)-

create_table :cricket do |t|
  t.jsonb :points
end

Before Validation

Earlier, Rails allowed the values to pass without any error, within the numericality validator, even when the value was not even an integer. Look at the example below to understand better -

class Cricketer < ApplicationRecord
  store_accessor :points, %i[scores]
end

>> Cricketer.create!(scores: "30")
#<Cricketer id: 1, points: {"scores" => "30"}, created_at: Sun, 04 Feb 2022 14:09:43.045301000 UTC +00:00, updated_at: Sun, 04 Feb 2022 14:09:43.045301000 UTC >

After Validation

Recently, Rails 7.0 introduced the only_numeric option to specify that only numeric options are allowed in the attributes. This method will, therefore, parse the value if it’s a string.

Look at the example below for a better understanding -

class Cricketer < ApplicationRecord
  store_accessor :points, %i[scores]
  validates_numericality_of :scores, only_numeric: true, allow_nil: true
end
>> Cricketer.create!(scores: "30")
'raise_validation_error': Validation failed: Scores is not a number (ActiveRecord::RecordInvalid)

>> Cricketer.create!(scores: 30)
#<Cricketer id: 1, points: {"scores" => 30}, created_at: Sun, 04 Feb 2022 14:09:43.045301000 UTC +00:00, updated_at: Sun, 04 Feb 2022 14:09:43.045301000 UTC >

Since the data doesn’t usually get serialized automatically in JSON columns, Rails added this option within the numericality validator to solve the problem of correct data serialization.

For more discussion, please refer to this PR.

Join Our Newsletter