Come aggiornare un record mongo usando Rogue con MongoCaseClassField quando la classe case contiene un'enumerazione scala


129

Sto aggiornando il codice esistente da Rogue 1.1.8a 2.0.0e lift-mongodb-recordda2.4-M5 to 2.5 .

Sto avendo difficoltà a scrivere MongoCaseClassField che contiene una scala enum, con cui potrei davvero aiutare.

Per esempio,

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)
  /// ...
}

Quando proviamo a scrivere in questo campo, otteniamo il seguente errore:

impossibile trovare il valore implicito per il parametro di prova di tipo com.foursquare.rogue.BSONType [MyCaseClass] .and (_. myCaseClass setTo myCaseClass)

Avevamo l'abitudine di farlo funzionare in Rogue 1.1.8, usando la nostra versione di the MongoCaseClassField, che rendeva superabile il metodo #formats. Ma quella funzione era inclusa nel record di lift-mongodb in 2.5-RC6, quindi abbiamo pensato che dovrebbe funzionare ora?


9
Sembra che la risposta sia stata fornita nell'elenco degli utenti non autorizzati
Asya Kamsky,

Risposte:


7

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

Ma più conveniente direttamente qui su StackOverFlow:


Scusa, avrei dovuto intervenire prima.

Uno dei problemi di vecchia data con Rogue era che era troppo facile creare accidentalmente un campo che non era serializzabile come BSON e che falliva in fase di esecuzione (quando si tenta di aggiungere quel valore a un oggetto DBO) piuttosto che al momento della compilazione .

Ho introdotto la classe di tipo BSONType per provare a risolvere questo problema. Il lato positivo è che rileva errori BSON in fase di compilazione. L'aspetto negativo è che devi fare una scelta quando si tratta di classi di casi.

Se si desidera farlo nel modo "corretto", definire la classe del caso più un "testimone" di tipo BSONT per quella classe del caso. Per definire un testimone BSONType, è necessario fornire la serializzazione da quel tipo a un tipo BSON. Esempio:

 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
   }
 }

Detto questo, questo può essere abbastanza oneroso se lo fai per ogni classe di casi. La seconda opzione è quella di definire un testimone generico che funzioni per qualsiasi classe di casi, se si dispone di uno schema di serializzazione generico:

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

Spero che questo ti aiuti,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.