ケースクラスにscala列挙が含まれている場合に、MongoCaseClassFieldでRogueを使用してmongoレコードを更新する方法


129

既存のコードRogue 1.1.82.0.0との間でアップグレードlift-mongodb-recordしてい2.4-M5 to 2.5ます。

MongoCaseClassFieldScala列挙型が含まれているため、実際にいくつかの助けを借りて書くことができません。

例えば、

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メソッドをオーバーライド可能にしていました。しかし、その機能は2.5-RC6のlift-mongodb-recordに含まれていたので、これでうまくいくと思いましたか?


9
回答が不正ユーザーリストで提供されたようです:grokbase.com/t/gg/rogue-users/1367nscf80/…–
Asya

回答:


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の長年の問題の1つは、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
   }
 }

とは言っても、ケースクラスごとに行うと、これは非常に負担になります。2番目のオプションは、一般的なシリアル化スキームがある場合に、あらゆるケースクラスで機能する一般的な監視を定義することです。

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

お役に立てれば、

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.