ExportXMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Minor - P4
    • None
    • Affects Version/s: 9.1.0, 9.1.1
    • Component/s: Validations
    • None
    • None
    • Ruby Drivers
    • None
    • None
    • None
    • None
    • None
    • None

      Since MONGOID-5842 (https://github.com/mongodb/mongoid/pull/6108), Mongoid::Validatable::NumericalityValidator reads every attribute through read_attribute_before_type_cast. An attribute that is not a field (such as a method that derives a value from a field) has no stored value, so the validator always sees nil:

      • without allow_nil/allow_blank, every value fails with "is not a number"
      • with allow_nil/allow_blank, the validation is skipped, so out-of-range values pass

      This worked in 9.0.x, and ActiveModel's numericality validator reads such attributes through the attribute reader.

      require 'bundler/inline'
      
      gemfile do
        source 'https://rubygems.org'
      
        gem 'mongoid', ENV.fetch('MONGOID_VERSION', '9.1.1')
      end
      
      Mongoid.configure do |config|
        config.clients.default = \{ hosts: ['localhost:27017'], database: 'mongoid_test' }
      end
      
      class Stake
        include Mongoid::Document
      
        field :ratio, type: Float
      
        # Not a field: a virtual attribute derived from one
        def percentage
          ratio * 100 if ratio
        end
      
        validates :percentage, numericality: \{ less_than_or_equal_to: 100 }
      end
      
      pp Mongoid::VERSION
      stake = Stake.new(ratio: 0.25)
      pp stake.percentage # => 25.0
      pp stake.valid?
      pp stake.errors.full_messages
      

      With 9.0.12:

      "9.0.12"
      25.0
      true
      []
      

      With 9.1.1:

      "9.1.1"
      25.0
      false
      ["Percentage is not a number"]
      

      The earlier approach in https://github.com/mongodb/mongoid/pull/6074 read the raw value only for numeric fields, so it did not have this problem. A fix that reads attributes that are not fields through read_attribute_for_validation is coming in a PR.

            Assignee:
            Unassigned
            Reporter:
            Tim Liner (EXT)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: