Cómo actualizar un registro mongo usando Rogue con MongoCaseClassField cuando la clase de caso contiene una enumeración de escala


129

Estoy actualizando el código existente a partir Rogue 1.1.8de 2.0.0y lift-mongodb-recorddesde 2.4-M5 to 2.5.

Tengo dificultades para escribir MongoCaseClassFieldque contenga una enumeración de escala, con la que realmente podría necesitar ayuda.

Por ejemplo,

object MyEnum extends Enumeration {
  type MyEnum = Value
  val A = Value(0)
  val B = Value(1)
}

case class MyCaseClass(name: String, value: MyEnum.MyEnum)

class MyMongo extends MongoRecord[MyMongo] with StringPk[MyMongo] {
  def meta = MyMongo

  class MongoCaseClassFieldWithMyEnum[OwnerType <: net.liftweb.record.Record[OwnerType], CaseType](rec : OwnerType)(implicit mf : Manifest[CaseType]) extends MongoCaseClassField[OwnerType, CaseType](rec)(mf) {
    override def formats = super.formats + new EnumSerializer(MyEnum)
  }

  object myCaseClass extends MongoCaseClassFieldWithMyEnum[MyMongo, MyCaseClass](this)
  /// ...
}

Cuando intentamos escribir en este campo, obtenemos el siguiente error:

no se pudo encontrar el valor implícito para el parámetro de evidencia de tipo com.foursquare.rogue.BSONType [MyCaseClass] .and (_. myCaseClass setTo myCaseClass)

Solíamos hacer que esto funcionara en Rogue 1.1.8, utilizando nuestra propia versión de MongoCaseClassField, que hizo que el método #formatos se pudiera anular. Pero esa característica se incluyó en lift-mongodb-record en 2.5-RC6, por lo que pensamos que esto debería funcionar ahora.


9
Parece que la respuesta se proporcionó en la lista de usuarios falsos
Asya Kamsky

Respuestas:


7

Respuesta proveniente de: http://grokbase.com/t/gg/rogue-users/1367nscf80/how-to-update-a-record-with-mongocaseclassfield-when-case-class-contains-a-scala-enumeration# 20130612woc3x7utvaoacu7tv7lzn4sr2q

Pero más conveniente directamente aquí en StackOverFlow:


Lo siento, debería haber intervenido aquí antes.

Uno de los problemas de larga data con Rogue era que era demasiado fácil crear accidentalmente un campo que no era serializable como BSON, y hacer que fallara en tiempo de ejecución (cuando intenta agregar ese valor a un DBObject) en lugar de en tiempo de compilación .

Introduje la clase de tipo BSONType para tratar de abordar esto. Lo bueno es que detecta errores BSON en tiempo de compilación. La desventaja es que debes elegir cuando se trata de clases de casos.

Si desea hacer esto de la manera "correcta", defina su clase de caso más un "testigo" de BSONType para esa clase de caso. Para definir un testigo BSONType, debe proporcionar la serialización de ese tipo a un tipo BSON. Ejemplo:

 case class TestCC(v: Int)

 implicit object TestCCIsBSONType extends BSONType[TestCC] {
   override def asBSONObject(v: TestCC): AnyRef = {
     // Create a BSON object
     val ret = new BasicBSONObject
     // Serialize all the fields of the case class
     ret.put("v", v.v)
     ret
   }
 }

Dicho esto, esto puede ser bastante pesado si lo estás haciendo para cada clase de caso. Su segunda opción es definir un testigo genérico que funcione para cualquier clase de caso, si tiene un esquema de serialización genérico:

 implicit def CaseClassesAreBSONTypes[CC <: CaseClass]: BSONType[CC] =
new BSONType[CC] {
   override def asBSONObject(v: CC): AnyRef = {
     // your generic serialization code here, maybe involving formats
   }
 }

Espero que esto ayude,

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.