Як оновити запис монго за допомогою Rogue з MongoCaseClassField, коли клас справи містить перерахунок шкали


129

Я оновлення існуючого коду від Rogue 1.1.8до 2.0.0і lift-mongodb-recordвід 2.4-M5 to 2.5.

Мені важко писати, MongoCaseClassFieldщо містить перерахунок скали, що я дійсно міг би скористатися деякою допомогою.

Наприклад,

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 надмірну. Але ця функція була включена в lift-mongodb-запис у 2.5-RC6, тож ми думали, що це має просто працювати зараз?


9
Схоже, відповідь була надана у списку користувачів шахраїв: grokbase.com/t/gg/rogue-users/1367nscf80/…
Ася Камський

Відповіді:


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 під час компіляції. Мінус у тому, що вам потрібно зробити вибір, коли справа стосується класів кейсів.

Якщо ви хочете зробити це "правильним" способом, визначте клас справи плюс 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
   }
 }

Сподіваюся, це допомагає,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.