mongo_orm Exception: missing bson key: publish_acl (Exceção)

Quando você amplia suas definições de campo nas classes de documentos mongo_orm, especificamente com documentos embutidos, você pode encontrar o seguinte erro de tempo de execução (!):

Exceção: falta da chave doson: (Exceção)

Isto não é um erro no seu código - o seu código está a subir, porque a estrutura da base de dados não é como espera que seja!

Aqui está o código de exemplo que estou usando para criar um Mongo Auth & ACL DB para a VerneMQ:

classe PublishACL < Mongo::ORM::EmbeddedDocument
     padrão de campo : Cordão
     campo max_qos : Int32
     campo permitido_retain : Bool
     campo max_payload_size : Int32
final

classe SubscribeACL < Mongo::ORM::EmbeddedDocument
     padrão de campo : Cordão
     campo max_qos : Int32
final

classe MQTTCredentials < Mongo::ORM::Document
     collection_name "vmq_acl_auth"
     ponto de montagem em campo : Cordão
     field client_id : String
     nome de usuário do campo : String
     passhash de campo : Cordel
     embeds_many :publish_acl, class_name: Papi::PublishACL 
     embeds_many :subscribe_acl, class_name: Papi::SubscribeACL

As teclas # são únicas por apikey_prefix
def self.getcredentials(apikey_prefix : String, bcm_serial : String)
     sucesso = falso
     1TP3Se as credenciais ainda não existirem, elas são adicionadas
     creds = self.first({"client_id" => bcm_serial, "username" => apikey_prefix})
     se !creds
         creds = self.new()
     final

     (corte)

    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 = verdadeiro

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

(corte)

final

final

Os ACLs foram inseridos depois de eu já ter entrado na base de dados sem eles:

imagem

Mensagem de erro MongoORM:

Exceção: chave bson ausente: publish_acl (Exceção)
   de src/db.cr:0:4 em 'from_bson'.
   de lib/mongo_orm/src/mongo_orm/querying.cr:93:7 em 'all' (todos)
   de lib/mongo_orm/src/mongo_orm/querying.cr:90:3 em 'all' (todos)

  (corte)

  de /usr/share/crystal/src/fiber.cr:47:34 em '->'.
   de ????

MongoORM não encontra os campos esperados publish_acl e subscribe_acl, que foram adicionados mais tarde.

Solução: solte (ou atualize) os documentos da Coleção, que não estão de acordo com seu novo padrão.

Isto é, por exemplo, como se parece uma entrada na base de dados para o acima exposto:

imagem

Bónus

em lib/mongo_orm/src/mongo_orm/extended_bson.cr:40: nenhuma sobrecarga combina 'BSON#[]=' com os tipos String, Array(Papi::PublishACL)

As sobrecargas são:

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

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

- BSON#[]=(chave, valor: Binário)

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

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

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

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

- BSON#[]=(chave, valor: Nulo)

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

- BSON#[]=(chave, valor : String)

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

- BSON#[]=(chave, valor: Tempo)

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

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

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

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

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

bson[_key] = valor

Você não pode fazer isto (actualmente) com o MongoORM:

creds.publish_acl = [ publish_acl ]

em vez disso, tens de usar:

creds.publish_acl << publish_acl