Лифт: как сделать эти отношения полиморфными? - PullRequest
2 голосов
/ 24 февраля 2011

Я получил запись, которая должна быть связана с одним из трех «списков», называющих их ListA ListB ListC. Я не мог понять, как это сделать с помощью LongMappedMapper.Итак, как я могу это сделать?

Я хотел, чтобы в Списке было несколько записей без необходимости указывать отношение 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 ]

2 голосов
/ 25 февраля 2011

Вы можете сделать это следующим образом:

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

Etam.

1 голос
/ 01 марта 2011

Это не идеально, но я создал обходной путь.Я не мог найти способ сделать полиморфизм в обоих направлениях хорошим способом.

Итак, начнем с роли.Роль внутренне имеет права RolePlayer, т.е.Пользователь или процесс или что-то еще.Ролевая игра играет роль в Appliable.Применимым является файл или папка или что-то еще в системе.у applialbe много ролей.у ролевого игрока много ролей.из-за того, что мне не нужно определять для каждого применимого отношения, и просто нужно расширять его с помощью свойства Appliable, я создал Workarout с appliableId и appliableClass в классе Role.

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] {

}

Это применимо, т.е.Папка или запись в блоге.

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)
  }
...