提升:如何使这些关系变得多态?

时间:2011-02-23 23:09:01

标签: scala lift

我有一个条目 它应该与三个“列表”之一相关,称它们为ListA ListB ListC 我无法弄清楚如何使用LongMappedMapper来做到这一点。 那我怎么能这样做呢?

我想让List有多个条目,而不必为每种列表指定listX关系。 所以

class Entry ...{
    object listA extends LongMappedMapper(this,ListA)
    object listB extends LongMappedMapper(this,ListB)
    ...
}

我想要类似的东西:

class Entry ...{
    object list extends PolyLongMappedMapper(this,ListA,ListB,ListC)
    //PolyLongMappedMapper i the example mapper what i want
    ...
}

或:

class Entry ...{
    object list extends PolyLongMappedMapper(this,BaseListTrait)
    //where BaseListTrait is a Trait shared by all List classes
    //PolyLongMappedMapper i the example mapper what i want
    ...
}

在Lift框架中有些东西我想要的是什么?什么可以与PolyLongMappedMapper相媲美? 或者有一种优雅的方法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

你可以这样做:

class A extends LongKeyedMapper[A] with IdPK {
    object entry extends LongMappedMapper(this, Entry)
    ...

class B extends LongKeyedMapper[B] with IdPK {
    object entry extends LongMappedMapper(this, Entry)
    ...

class C extends LongKeyedMapper[C] with IdPK {
    object entry extends LongMappedMapper(this, Entry)
    ...

class Entry extends LongKeyedMapper[Entry] with IdPK {
    def aList = A.findAll(By(A.entry, this))
    def bList = B.findAll(By(B.entry, this))
    def cList = C.findAll(By(C.entry, this))
    ...

你的名单是:

e.aList, e.bList, e.cList

当:

val e: Entry

艾格。

答案 1 :(得分:1)

它并不完美,但我创造了一种解决方法。 我无法找到一种方法以一种很好的方式在两个方向上进行多态性。

让我们从角色开始吧。角色在内部保存RolePlayer的权利,即。用户或进程或其他什么。 角色扮演者在Appliable中扮演角色。应用程序是文件或文件夹或系统中的其他内容。 applialbe有很多角色。角色扮演者有很多角色。因为不必为每个appliable定义关系,只需要使用trait扩展Appliable我在Role类中创建了Workarout wit appliableId和appliableClass。

class Role extends BaseModel[Role] {
  def getSingleton = Role

  object appliableId extends MappedLong(this)

  object appliableClass extends MappedString(this, 300)

  def setAppliable (appliable: Appliable[_]) = {
    rolePlayerId(appliable.id.is)
    rolePlayerClass(validClassName(appliable))
  }

  def validClassName(appliable: Appliable[_]) = {
    appliable.getClass.getName
  }
  def appliable={
    Class.forName(appliableClass).asInstanceOf[Appliable[_]].findById(appliableId.is)
  }
   object rolePlayerId extends MappedLong(this)

  object rolePlayerClass extends MappedString(this, 300)

  def setRolePlayer (appliable: Appliable[_]) = {
    rolePlayerId(appliable.id.is)
    rolePlayerClass(validClassName(appliable))
  }


  def rolePlayer={
    Class.forName(rolePlayerClass).asInstanceOf[RolePlayer[_]].findById(rolePlayerId.is)
  }
}

object Role extends Role with BaseMetaModel[Role] {

}

这是Appliable即。文件夹或博客条目。

trait Appliable[T <: BaseModel[T]] {
  this: T =>

  def findById(i: Long): Box[T]

  def id: MappedLong[T]

  def getRoles = {
    Role.findAll(By(Role.appliableId, id.is), By(Role.appliableClass, Role.validClassName(Appliable.this)))
  }

  def addRole(role: Role) = {
    role.setAppliable(Appliable.this)
  }
}

class App1 extends BaseModel[App1] with Appliable[App1] {
  def getSingleton = App1
}

object App1 extends App1 with BaseMetaModel[App1]

class App2 extends BaseModel[App2] with Appliable[App2] {
  def getSingleton = App2
}

object App2 extends App2 with BaseMetaModel[App2]

这是FunSuite的简短测试:

test("appliables should have roles") {
    val a = App1.create
    val b = App2.create
    List(a, b).map(_.save)
    val ra1 = Role.create.setAppliable(a)
    val ra2 = Role.create.setAppliable(a)
    val rb1 = Role.create.setAppliable(b)
    val rb2 = Role.create.setAppliable(b)

    List(ra1, ra2, rb1, rb2).map(_.save)
    val ar = App1.find(By(a.id, a.id.is)).get.getRoles.toList
    assert(ar(0) == ra1, ar(0) + " was not " + ra1)
    assert(ar(1) == ra2, ar(1) + " was not " + ra2)
    val br = b.getRoles.toList
    assert(br(0) == rb1, br(0) + "  was not " + rb1)
    assert(br(1) == rb2, br(1) + " was not " + rb2)
  }