如何创建megaprotouser String的主键id字段而不是Long?

时间:2014-09-15 04:02:12

标签: scala lift traits

我正在尝试将MegaProtoUser String的主键ID字段设为Long。我正在考虑扩展MegaProtoUser特征并覆盖其成员,但我必须覆盖受保护的类(我认为),这在Scala中是不允许的。因为我无法弄清楚如何扩展MegaProtoUser,所以我决定编写我自己的这个特性版本(见下文)并将其混合如下:

class User extends StringMegaProtoUser[User] with CreatedUpdatedNotEditable {
  def getSingleton = User //
  ...
}

这不起作用。编译器抱怨我在User模型中定义的外键不是正确的类型。任何人都可以建议如何扩展MegaProtoUser,以便它使用String id而不是Long id?

谢谢!

更新:在下面的代码中,为了回应下面的评论,我将KeyedMapper[Long, T]更改为KeyedMapper[String, T]。这没有解决问题:当我使用这个新的StringMegaProtoUser时,编译器给我以下错误:

[error] ..../src/main/scala/code/model/User.scala:39: type mismatch;
[error]  found   : code.model.User.type
[error]  required: net.liftweb.mapper.KeyedMetaMapper[String,code.model.User]
[error]   def getSingleton = User // what's the "meta" server

有人可以建议如何解决这个问题吗?谢谢!

trait StringProtoUser[T <: net.liftweb.mapper.StringProtoUser[T]]
extends KeyedMapper[Long, T] with UserIdAsString {
  self: T =>

  override def primaryKeyField: MappedStringIndex[T] = id

  /**
   * The primary key field for the User.  You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val id = new MyMappedLongClass(this) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val id: MappedStringIndex[T] = new MyMappedStringClass(this)

  protected class MyMappedStringClass(obj: T) extends MappedStringIndex(obj, 50)

  /**
   * Convert the id to a String
   */
  def userIdAsString: String = id.get.toString

  /**
   * The first name field for the User.  You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val firstName = new MyFirstName(this, 32) {
   *   println("I am doing something different")
   * }
   * </pre>
   */

  lazy val firstName: MappedString[T] = new MyFirstName(this, 32)

  protected class MyFirstName(obj: T, size: Int) extends
MappedString(obj, size) {
    override def displayName = fieldOwner.firstNameDisplayName
    override val fieldId = Some(Text("txtFirstName"))
  }

  /**
   * The string name for the first name field
   */
  def firstNameDisplayName = S.?("first.name")

  /**
   * The last field for the User.  You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val lastName = new MyLastName(this, 32) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val lastName: MappedString[T] = new MyLastName(this, 32)

  protected class MyLastName(obj: T, size: Int) extends
MappedString(obj, size) {
    override def displayName = fieldOwner.lastNameDisplayName
    override val fieldId = Some(Text("txtLastName"))
  }

  /**
   * The last name string
   */
  def lastNameDisplayName = S.?("last.name")

  /**
   * The email field for the User.  You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val email = new MyEmail(this, 48) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val email: MappedEmail[T] = new MyEmail(this, 48)

  protected class MyEmail(obj: T, size: Int) extends MappedEmail(obj, size) {
    override def dbIndexed_? = true
    override def validations = valUnique(S.?("unique.email.address"))
_ :: super.validations
    override def displayName = fieldOwner.emailDisplayName
    override val fieldId = Some(Text("txtEmail"))
  }

  /**
   * The email first name
   */
  def emailDisplayName = S.?("email.address")

  /**
   * The password field for the User.  You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val password = new MyPassword(this) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val password: MappedPassword[T] = new MyPassword(this)

  protected class MyPassword(obj: T) extends MappedPassword(obj) {
    override def displayName = fieldOwner.passwordDisplayName
  }

  /**
   * The display name for the password field
   */
  def passwordDisplayName = S.?("password")

  /**
   * The superuser field for the User.  You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val superUser = new MySuperUser(this) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val superUser: MappedBoolean[T] = new MySuperUser(this)

  protected class MySuperUser(obj: T) extends MappedBoolean(obj) {
    override def defaultValue = false
  }

  def niceName: String = (firstName.get, lastName.get, email.get) match {
    case (f, l, e) if f.length > 1 && l.length > 1 => f+" "+l+" ("+e+")"
    case (f, _, e) if f.length > 1 => f+" ("+e+")"
    case (_, l, e) if l.length > 1 => l+" ("+e+")"
    case (_, _, e) => e
  }

  def shortName: String = (firstName.get, lastName.get) match {
    case (f, l) if f.length > 1 && l.length > 1 => f+" "+l
    case (f, _) if f.length > 1 => f
    case (_, l) if l.length > 1 => l
    case _ => email.get
  }

  def niceNameWEmailLink = <a href={"mailto:"+email.get}>{niceName}</a>
}

trait StringMegaProtoUser[T <: StringMegaProtoUser[T]] extends
StringProtoUser[T] {
  self: T =>

  /**
   * The unique id field for the User. This field
   * is used for validation, lost passwords, etc.
   * You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val uniqueId = new MyUniqueId(this, 32) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val uniqueId: MappedUniqueId[T] = new MyUniqueId(this, 32)

  protected class MyUniqueId(obj: T, size: Int) extends
MappedUniqueId(obj, size) {
    override def dbIndexed_? = true
    override def writePermission_?  = true
  }

  /**
   * The has the user been validated.
   * You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val validated = new MyValidated(this, 32) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val validated: MappedBoolean[T] = new MyValidated(this)

  protected class MyValidated(obj: T) extends MappedBoolean[T](obj) {
    override def defaultValue = false
    override val fieldId = Some(Text("txtValidated"))
  }

  /**
   * The locale field for the User.
   * You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val locale = new MyLocale(this, 32) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val locale = new MyLocale(this)

  protected class MyLocale(obj: T) extends MappedLocale[T](obj) {
    override def displayName = fieldOwner.localeDisplayName
    override val fieldId = Some(Text("txtLocale"))
  }

  /**
   * The time zone field for the User.
   * You can override the behavior
   * of this field:
   * <pre name="code" class="scala">
   * override lazy val timezone = new MyTimeZone(this, 32) {
   *   println("I am doing something different")
   * }
   * </pre>
   */
  lazy val timezone = new MyTimeZone(this)

  protected class MyTimeZone(obj: T) extends MappedTimeZone[T](obj) {
    override def displayName = fieldOwner.timezoneDisplayName
    override val fieldId = Some(Text("txtTimeZone"))
  }

  /**
   * The string for the timezone field
   */
  def timezoneDisplayName = S.?("time.zone")

  /**
   * The string for the locale field
   */
  def localeDisplayName = S.?("locale") 
}

0 个答案:

没有答案