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

Я обновляю существующий код от 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]        .and(_. myCaseClass setTo myCaseClass)

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

Ответ 1

Ответ от: 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, и иметь его fail при выполнении (когда вы пытаетесь добавить это значение в 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
   }
 }

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

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

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