Shafique Jamal
Shafique Jamal

Reputation: 1688

How do I make a trait that I can mix into mapped fields to that I don not have to override the same properties for many fields in a database?

In the Scala Lift framework, how do I make a trait that I can mix into mapped fields to that I don not have to override the same properties for many fields in a database?

I would like to eliminate some redundancy in the code below. Specifically, I do not want to have to repeatedly add:

override def writePermission_? = false
override def readPermission_? = false
override def shouldDisplay_? = false
override def show_? = false
override def dbDisplay_? = false

for the several db fields. I am thinking that the way to go about this would be to write a trait that looks something like this:

trait PrivateField extends ...??? {
    override def writePermission_? = false
    override def readPermission_? = false
    override def shouldDisplay_? = false
    override def show_? = false
    override def dbDisplay_? = false
}

and then mix this into the object overrides as follows:

object owner extends MappedLongForeignKey(this, User) with PrivateField
object status extends MappedInt(this) with PrivateField

etc. Is this a good way to approach the problem? If so, any suggestions on how to write the trait? Below is the code for which I want to reduce the redundancy.

class Mytable extends LongKeyedMapper[Mytable] with IdPK {

  def getSingleton = Myclass

  object owner extends MappedLongForeignKey(this, User) {
    override def writePermission_? = false
    override def readPermission_? = false
    override def shouldDisplay_? = false
    override def show_? = false
    override def dbDisplay_? = false
  }
  object description extends MappedString(this, 140)
  object name extends MappedString(this, 140)
  object status extends MappedInt(this) {
    override def writePermission_? = false
    override def readPermission_? = false
    override def shouldDisplay_? = false
    override def show_? = false
    override def dbDisplay_? = false
  }
  object entry_number extends MappedInt(this) {
    override def writePermission_? = false
    override def readPermission_? = false
    override def shouldDisplay_? = false
    override def show_? = false
  }
  object quanitity extends MappedDecimal(this, MathContext.DECIMAL64, 2) {
    override def writePermission_? = false
    override def readPermission_? = false
    override def shouldDisplay_? = false
    override def show_? = false
    override def dbDisplay_? = false
  }
}

object Mytable extends Mytable with LongKeyedMetaMapper[Mytable] with CRUDify[Long, Mytable] {

  override def editMenuLoc:Box[Menu] = Empty
  override def deleteMenuLoc:Box[Menu] = Empty
  override def viewMenuLoc:Box[Menu] = Empty
  override def createMenuLocParams: List[Loc.AnyLocParam] = List(If(User.loggedIn_? _, "Not logged in"))
  override def showAllMenuLocParams: List[Loc.AnyLocParam] = List(If(User.loggedIn_? _, "Not logged in"))

  override def findForList(start: Long, cnt: Int): List[Mytable] =
    findAll(StartAt(start), MaxRows(cnt), By(owner, User.currentUser))

  override def findForParam(in: String): Box[Mytable] =
    for {
      user <- User.currentUser
      id <- Helpers.asLong(in)
      mytable <- find(By(this.id, id), By(owner, user))
    } yield mytable
}

Thanks,

Upvotes: 0

Views: 32

Answers (1)

Sean Vieira
Sean Vieira

Reputation: 159955

The simplest way is probably to use a self type annotation:

trait PrivateField[FieldType <: Any, OwnerType <: Mapper[OwnerType]] {
  self: MappedField[FieldType, OwnerType] =>
  override def writePermission_? = false
  override def readPermission_? = false
  override def shouldDisplay_? = false
  override def show_? = false
}

Then you can use it in this manner:

MappedInt(this) with PrivateField[Int, Mytable]

Upvotes: 1

Related Questions