Yet another trait question :-(
I am mixing in the IdPK trait into my Lift Mapper models as follows:
class Test1 extends LongKeyedMapper[Test1] with IdPK {
I would like to switch to using String indexes instead of Long indexes (I don't want to but I have to, for now). I am trying to write a trait StringIdPK
to replace the IdPK
trait. Here is my attempt:
trait StringIdPK /* extends BaseLongKeyedMapper */ {
self: KeyedMapper[String] =>
def primaryKeyField = id
object id extends MappedStringIndex(this, 50)
}
(I based this on the IdPK
trait which is as follows:
trait IdPK /* extends BaseLongKeyedMapper */ {
self: BaseLongKeyedMapper =>
def primaryKeyField = id
object id extends MappedLongIndex[MapperType](this.asInstanceOf[MapperType])
}
the code for this trait can be found here)
When I try to compile, I get the following error:
wrong number of type arguments for net.liftweb.mapper.KeyedMapper, should be 2
The specification for KeyedMapper
(which can be found here) is:
trait KeyedMapper[KeyType, OwnerType <: KeyedMapper[KeyType, OwnerType]] extends Mapper[OwnerType] with BaseKeyedMapper
I need to better understand what OwnerType <: KeyedMapper[KeyType, OwnerType]
means and how to accommodate it in my custom trait above. So my question is: what am I doing wrong in my definition of the trait StringIdPK
above? (This will help me to understand how to deal with OwnerType <: KeyedMapper[KeyType, OwnerType]
).
Thanks!
UPDATE: I think the following comes close to solving it (see below - I took some of the code from here). It is still not quite right, since the compiler still complains about the FK objects I extended not having foreign meta defined.
trait BaseStringKeyedMapper extends BaseKeyedMapper{
override type TheKeyType = String
}
trait StringKeyedMapper[OwnerType <: StringKeyedMapper[OwnerType]] extends KeyedMapper[String, OwnerType] with BaseStringKeyedMapper {
self: OwnerType =>
}
trait StringKeyedMetaMapper[A <: StringKeyedMapper[A]] extends KeyedMetaMapper[String, A] {
self: A =>
}
trait StringIdPK {
self: BaseStringKeyedMapper =>
def primaryKeyField = id
object id extends MappedStringIndex[MapperType](this.asInstanceOf[MapperType], 50)
}
Also, there was a posting about this issue on the lift google group here, but it seems unresolved.
I think the following solves it (I'm unable to confirm right now because I am working through another issue before I can really test it, but this seems to work so far. I took some of the code from here and here. I will update this as I learn more about this implementation):
trait BaseStringKeyedMapper extends BaseKeyedMapper{
override type TheKeyType = String
}
trait StringKeyedMapper[OwnerType <: StringKeyedMapper[OwnerType]] extends KeyedMapper[String, OwnerType] with BaseStringKeyedMapper {
self: OwnerType =>
}
trait StringKeyedMetaMapper[A <: StringKeyedMapper[A]] extends KeyedMetaMapper[String, A] {
self: A =>
}
trait StringIdPK {
self: BaseStringKeyedMapper =>
def primaryKeyField = id
object id extends MappedStringIndex[MapperType](this.asInstanceOf[MapperType], 50) {
override def writePermission_? = true // if u want to set it via your code, keep this true
override def dbAutogenerated_? = false
override def dbNotNull_? = true
// override def writePermission_? = false
override def readPermission_? = true
override def shouldDisplay_? = true
override def show_? = true
override def dbDisplay_? = true
override def validations = valUnique(S.?("Must be unique")) _ :: super.validations
}
}
I've added some overrides to the id
field for mixing this in along with CRUDify. For some reason that I cannot figure out, valUnique
does not work (other validations such as valMinLen
do work, however). I will post a new question about this.