update - mongodb operaciones
Cómo actualizar un registro de mongo utilizando Rogue con MongoCaseClassField cuando la clase de caso contiene una escala Enumeración (1)
Estoy actualizando el código existente de Rogue 1.1.8
a 2.0.0
y lift-mongodb-record
de 2.4-M5 to 2.5
.
Tengo dificultades para escribir MongoCaseClassField
que contiene una MongoCaseClassField
enum, 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 tratamos de 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 tener esto funcionando en Rogue 1.1.8, al usar nuestra propia versión de MongoCaseClassField
, lo que hacía que el método #formats fuera invalidable. Pero esa característica se incluyó en lift-mongodb-record en 2.5-RC6, ¿así que pensamos que esto debería funcionar ahora?
Respuesta procedente de: grokbase.com/t/gg/rogue-users/1367nscf80/…
Pero más conveniente directamente aquí en :
Lo siento, debería haber intervenido aquí antes.
Uno de los viejos problemas con Rogue era que era demasiado fácil crear accidentalmente un campo que no fuera serializable como BSON y hacerlo fallar en tiempo de ejecución (cuando intentas agregar ese valor a un objeto DBObject) en lugar de en tiempo de compilación. .
Introduje la clase de tipo BSONType para intentar abordar esto. La ventaja es que atrapa errores BSON en tiempo de compilación. La desventaja es que debe 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" 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 haces 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,