mongo_orm Excepción: falta la clave bson: publish_acl (Excepción)

Cuando extiendas tus definiciones de campo en las clases documentales de mongo_orm, específicamente con documentos incrustados, podrías encontrarte con el siguiente error en tiempo de ejecución (!):

Excepción: falta la clave bson: (Excepción)

¡Esto no es un error en su código - su código está levantando, porque la estructura de la base de datos no es como espera que sea!

Aquí está el código de ejemplo que estoy usando para crear una base de datos Mongo Auth & ACL para VerneMQ:

class PublishACL < Mongo::ORM::EmbeddedDocument
     patrón de campo : Cadena
     field max_qos : Int32
     campo allowed_retain : Bool
     field max_payload_size : Int32
fin

class SubscribeACL < Mongo::ORM::EmbeddedDocument
     patrón de campo : Cadena
     field max_qos : Int32
fin

class MQTTCredentials < Mongo::ORM::Document
     collection_name "vmq_acl_auth"
     campo punto de montaje : Cadena
     field client_id : Cadena
     campo nombre de usuario : Cadena
     campo passhash : Cadena
     embeds_many :publish_acl, class_name: Papi::PublishACL 
     embeds_many :subscribe_acl, class_name: Papi::SubscribeACL

Las claves # son únicas por apikey_prefix
def self.getcredentials(apikey_prefix : String, bcm_serial : String)
     éxito = falso
     1TP3Si las credenciales no existen todavía, se añaden
     creds = self.first({"client_id" => bcm_serial, "username" => apikey_prefix})
     si !creds
         creds = self.new()
     fin

     (snip)

    publish_acl = PublishACL.new()
     subscribe_acl = SubscribeACL.new()
     # https://vernemq.com/docs/configuration/db-auth.html
     publish_acl.pattern = "#"
     publish_acl.max_qos = 2 # Int
     publish_acl.allowed_retain = true

    subscribe_acl.pattern = "#"
     subscribe_acl.max_qos = 2
    
     creds.publish_acl << publish_acl
     creds.subscribe_acl << subscribe_acl 
     éxito = creds.save

(snip)

fin

fin

Las ACL se insertaron después de que ya tenía entradas en la base de datos sin ellas:

imagen

Mensaje de error de MongoORM:

Excepción: falta la clave bson: publish_acl (Excepción)
   from src/db.cr:0:4 in 'from_bson'
   from lib/mongo_orm/src/mongo_orm/querying.cr:93:7 in 'all'
   from lib/mongo_orm/src/mongo_orm/querying.cr:90:3 in 'all'

  (snip)

  de /usr/share/crystal/src/fiber.cr:47:34 en '->'
   de la que no se puede prescindir.

MongoORM no encuentra los campos esperados publish_acl y subscribe_acl, que fueron añadidos posteriormente.

Solución: abandone (o actualice) los documentos de la colección que no se ajusten a su nueva norma.

Este es, por ejemplo, el aspecto de una entrada de la base de datos para lo anterior:

imagen

Bono

en lib/mongo_orm/src/mongo_orm/extended_bson.cr:40: ninguna sobrecarga coincide con 'BSON#[]=' con los tipos String, Array(Papi::PublishACL)

Las sobrecargas son:

- BSON#[]=(clave, valor : Int32)

- BSON#[]=(clave, valor : Int64)

- BSON#[]=(clave, valor : Binario)

- BSON#[]=(clave, valor : Bool)

- BSON#[]=(clave, valor : Float64 | Float32)

- BSON#[]=(clave, valor : MinKey)

- BSON#[]=(clave, valor : MaxKey)

- BSON#[]=(clave, valor : Nil)

- BSON#[]=(clave, valor : ObjectId)

- BSON#[]=(clave, valor : Cadena)

- BSON#[]=(clave, valor : Símbolo)

- BSON#[]=(clave, valor : Tiempo)

- BSON#[]=(clave, valor : Timestamp)

- BSON#[]=(clave, valor : Código)

- BSON#[]=(clave, valor : BSON)

- BSON#[]=(clave, valor : Regex)

- BSON#[]=(clave, valor : Mongo::ORM::EmbeddedDocument)

bson[_key] = valor

Usted no puede hacer esto (actualmente) con MongoORM:

creds.publish_acl = [ publish_acl ]

en su lugar tienes que usar:

creds.publish_acl << publish_acl