This blog is part of our Rails 7 series.
Rails 7.0.1 introduces only_numeric option to numericality validator which specifies whether the value has to be an instance of Numeric. The default behavior is to attempt parsing the value if it is a String.
When the database field is a float column, the data will get serialized to the correct type. In the case of a JSON column, serialization doesn't take place.
As a resolution, Rails 7 has added only_numeric option to numericality validator.
We will see it in action.
To demonstrate, we need to generate a table that has a json/jsonb column.
1# migration 2create_table :users do |t| 3 t.jsonb :personal 4end
Before Validation
1# Model 2class User < ApplicationRecord 3 store_accessor :personal, %i[age tooltips] 4end
1# rails console 2>> User.create!(age: '29') 3=> #<User id: 1, preferences: {"age"=>"29"}, created_at: Sun, 16 Jan 2022 14:09:43.045301000 UTC +00:00, updated_at: Sun, 16 Jan 2022 14:09:43.045301000 UTC +00:00>
After Validation
1# Model 2class User < ApplicationRecord 3 store_accessor :personal, %i[age tooltips] 4 validates_numericality_of :age, only_numeric: true, allow_nil: true 5end
1# rails console 2>> User.create!(age: '29') 3=> 'raise_validation_error': Validation failed: Age is not a number (ActiveRecord::RecordInvalid) 4 5>> User.create!(age: 29) 6=> #<User id: 2, preferences: {"age"=>29}, created_at: Sun, 16 Jan 2022 14:15:44.599934000 UTC +00:00, updated_at: Sun, 16 Jan 2022 14:15:44.599934000 UTC +00:00>
Please check out this pull request for more details.