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

_id with custom type can't be queried

    • Type: Icon: Bug Bug
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Query
    • None

      Originally posted as a discussion on GitHub: https://github.com/mongodb/mongoid/discussions/5671

      I have a simple model with custom field types here:
       

      class BuggyModel
        include ::Mongoid::Document
        store_in collection: 'buggy_models'
      
        class HexBytes
          class << self
            def mongoize(hex_string)
              return nil unless hex_string.present?
              [hex_string].pack('H*').then do |bin_content|
                ::BSON::Binary.new(bin_content)
              end
            end
      
            def demongoize(binary)
              return nil unless binary.present?
              binary.data.then do |bin_content|
                return nil unless bin_content.present?
                bin_content.unpack1('H*')
              end
            end
      
            # this is weird
            def evolve(hex_string)
              mongoize(hex_string)
            end
          end
        end
      
        field :_id, type: HexBytes
      end 

      With the declaration, this works:
       

      BuggyModel.create!({ _id: '01' }) 

      but these failed:
       

      BuggyModel.find('01')
      BuggyModel.where({ _id: '04' }).first_or_create! 

      So I remove evolve:
       

      class BuggyModel
        include ::Mongoid::Document
        store_in collection: 'buggy_models'
      
        class HexBytes
          class << self
            def mongoize(hex_string)
              return nil unless hex_string.present?
              [hex_string].pack('H*').then do |bin_content|
                ::BSON::Binary.new(bin_content)
              end
            end
      
            def demongoize(binary)
              return nil unless binary.present?
              binary.data.then do |bin_content|
                return nil unless bin_content.present?
                bin_content.unpack1('H*')
              end
            end
          end
        end
      
        field :_id, type: HexBytes
      end 

      Now the test cases above work, but:
       

      # This failed to fetch the record
      BuggyModel.where({ _id: '01' }).first
      # which render the following useless
      BuggyModel.where({ _id: '04' }).first_or_create! 

      To make it more approachable as test cases, I expect
       

      BuggyModel.create!({ _id: '01' })
      BuggyModel.where({ _id: '01' }).first_or_create!
      BuggyModel.where({ _id: '02' }).first_or_create! 

      to create exactly two documents without raising an exception. (on an originally-blank collection) And all the following
       

      BuggyModel.find('01')
      BuggyModel.where({ _id: '01' }).first
      BuggyModel.where({ _id: '02' }).first 

      to fetch Document#01Document#01, and Document#02 respectively successfully after the steps above.

      I can't seem to accomplish that with any configurations I can come up with.

      P.S. If you are curious, what are the real-world use cases: I use certificate thumbprints as _id in a collection that stores digital certificates.

            Assignee:
            jamis.buck@mongodb.com Jamis Buck
            Reporter:
            jamis.buck@mongodb.com Jamis Buck
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: