วิธีอัพเดตเร็กคอร์ด mongo โดยใช้ Rogue ด้วย MongoCaseClassField เมื่อคลาสเคสมี scala Enumeration


129

ฉันกำลังอัพเกรดรหัสที่มีอยู่จากRogue 1.1.8ไป2.0.0และจากlift-mongodb-record2.4-M5 to 2.5

ฉันมีปัญหาในการเขียนMongoCaseClassFieldซึ่งมี scala enum ซึ่งฉันสามารถใช้ความช่วยเหลือได้บ้าง

ตัวอย่างเช่น,

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 วิธี overridable แต่ฟีเจอร์ดังกล่าวนั้นรวมอยู่ในการยก -mongodb-record ใน 2.5-RC6 ดังนั้นเราคิดว่าตอนนี้ควรจะใช้งานได้หรือไม่


9
ดูเหมือนว่าคำตอบที่ให้ไว้ในรายชื่อผู้ใช้ที่หลอกลวง: grokbase.com/t/gg/rogue-users/1367nscf80/…
Asya Kamsky

คำตอบ:


7

คำตอบมาจาก: http://grokbase.com/t/gg/rogue-users/1367nscf80/how-to-update-a-record-with-mongocaseclassfield-when-case-class-contain-a-scala-enumeration # 20130612woc3x7utvaoacu7tv7lzn4sr2q

แต่สะดวกยิ่งขึ้นตรงนี้ใน StackOverFlow:


ขออภัยฉันควรจะตีระฆังที่นี่เร็วกว่านี้

หนึ่งในปัญหาที่เกิดขึ้นยาวนานกับ Rogue คือมันง่ายเกินไปที่จะสร้างเขตข้อมูลที่ไม่สามารถปรับให้เป็น BSON ได้โดยไม่ตั้งใจและทำให้มันล้มเหลวขณะใช้งานจริง (เมื่อคุณพยายามเพิ่มมูลค่านั้นลงใน DBObject) แทนที่จะรวบรวมเวลา .

ฉันแนะนำคลาสประเภท BSONType เพื่อพยายามแก้ไขปัญหานี้ ข้อเสียคือมันจับข้อผิดพลาด BSON ในเวลารวบรวม ข้อเสียคือคุณต้องเลือกเมื่อมันมาถึงกรณีคลาส

หากคุณต้องการทำเช่นนี้ "ถูกต้อง" วิธีกำหนดคลาสเคสของคุณบวกกับ "พยาน" BSONType สำหรับคลาสเคสนั้น ในการกำหนดพยาน BSON คุณจะต้องจัดให้มีการทำให้เป็นอันดับจากประเภทนั้นเป็นประเภท 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
   }
 }

หวังว่าจะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.