Как обновить запись mongo с помощью Rogue с MongoCaseClassField, когда класс case содержит перечисление scala

129

Я обновление существующего кода от Rogue 1.1.8до 2.0.0и lift-mongodb-recordот 2.4-M5 to 2.5.

Мне трудно написать, MongoCaseClassFieldчто содержит перечисление scala, с которым мне действительно нужна помощь.

Например,

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

Когда мы пытаемся написать в это поле, мы получаем следующую ошибку:

не удалось найти неявное значение для параметра доказательства типа com.foursquare.rogue.BSONType [MyCaseClass]. и (_. myCaseClass setTo myCaseClass)

Раньше у нас это работало в Rogue 1.1.8, используя нашу собственную версию MongoCaseClassField, которая сделала метод #formats переопределяемым. Но эта функция была включена в запись lift-mongodb-record в 2.5-RC6, поэтому мы подумали, что это должно работать сейчас?

Джунейт Донмез
источник
9
Похоже, ответ был дан в
Ася Камский

Ответы:

7

Ответ от: http://grokbase.com/t/gg/rogue-users/1367nscf80/how-to-update-a-record-with-mongocaseclassfield-when-case-class-contains-a-scala-enumeration# 20130612woc3x7utvaoacu7tv7lzn4sr2q

Но удобнее прямо здесь, на StackOverFlow:


Извини, я должен был вмешаться раньше.

Одна из давних проблем с Rogue заключалась в том, что было слишком легко случайно создать поле, которое не было сериализовано как BSON, и дать ему сбой во время выполнения (когда вы пытаетесь добавить это значение в DBObject), а не во время компиляции. ,

Я представил класс типов BSONType, чтобы попытаться решить эту проблему. Положительным моментом является то, что он обнаруживает ошибки BSON во время компиляции. Обратной стороной является необходимость выбора, когда дело доходит до классов case.

Если вы хотите сделать это «правильным» способом, определите свой класс дела плюс BSONType «свидетель» для этого класса дела. Чтобы определить свидетеля BSONType, вам необходимо обеспечить сериализацию из этого типа в тип BSON. Пример:

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

Тем не менее, это может быть довольно обременительным, если вы делаете это для каждого класса кейсов. Второй вариант - определить общий свидетель, который работает для любого класса дела, если у вас есть общая схема сериализации:

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

Надеюсь это поможет,

Валентин Монмирай
источник