Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-5456

New "uncastable" behavior does't work with ActiveSupport::Duration

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 8.0.3
    • Affects Version/s: 8.0.2
    • Component/s: Attributes
    • Labels:
      None
    • Minor Change

      While trying to upgrade from 7.5.1 to 8.0.2 I noticed the new "uncastable type" behavior documented here: https://www.mongodb.com/docs/mongoid/master/release-notes/mongoid-8.0/#storing-retrieving-evolving-uncastable-values.

      And unfortunately it created a lot of failures in my application where I use ActiveSupport::Duration (e.g. 5.minutes, 2.hours, 23.seconds, etc..). These types are castable to Integer and Float and usually stored in these kind of fields depending on the precision wanted so they are definitely not "uncastable". I have them stored in Float for the last 10 years and noticed they are not accepted any more, it just keeps nil since 8.0.2. I thought: Ok that's annoying but maybe that's what AR does so it could make sense to align even if would be pretty annoying to have to manually convert everywhere, but AFAICS it's not the case, I just tested in AR 7.0.3.1 (latest version) and it casts duration to integer or float attributes without problem.

      So before spending hours rewriting my app for a potential bug, I would rather ask if breaking this is actually a desired divergence from AR in Mongoid ? And what would justify this ? I support this is more likely a missed case in the way Mongoid casts values which doesn't play well with Duration? (I suppose it doesn't use the standard `to_f`? because Duration responds to it).

      Here is a simple reproduction example:

      #!/usr/bin/env ruby
      
      require 'bundler/inline'
      
      gemfile do
        source 'https://rubygems.org'
        gem 'mongoid', '7.5.1'
        gem 'activesupport'
      end
      
      require 'mongoid'
      
      Mongoid.configure { |c| c.clients.default = { hosts: ['localhost'], database: 'test' } }
      puts Mongoid::VERSION
      puts Mongo::VERSION
      
      class Model
        include Mongoid::Document
        include Mongoid::Timestamps
      
        field :a, type: Integer
        field :b, type: Float
      end
      
      model = Model.new(a: 2.hours, b: 1.minute / 178.0)
      p model
      # With 8.0.2:
      #<Model _id: 62e93da5756457011a9a825f, created_at: nil, updated_at: nil, a: nil, b: nil>
      
      # With 7.5.1:
      #<Model _id: 62e93dcd756457019ae0d98a, created_at: nil, updated_at: nil, a: 7200, b: 0.33707865168539325>
      
      p 2.hours.to_i
      # 7200
      p 2.hours.to_f
      # 7200.0
      

      Thanks for the clarification and sorry if I missed any existing discussion about this, I searched for it but couldn't find anything yet.

            Assignee:
            neil.shweky@mongodb.com Neil Shweky (Inactive)
            Reporter:
            bigbourin@gmail.com Adrien Jarthon
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: