创建两种不同类型的用户(Scala,Lift)

3 design-patterns scala class lift

我正在创建一个需要两种类型用户的网站:学生和提供者.在传统的java设置中,我将创建一个用户类(或接口),然后创建两个继承自用户的类.这是scala中最好的课程,使用"extends"和"with"修饰符?如果这确实是最好的方式(我怀疑它是),那么在数据库中映射这个的最佳方法是什么?最好保留一个"类型"列,然后将其设置为一个或另一个?

第二个问题是如何使用视图.根据用户的类型,显示将是非常不同的,因此我认为将涉及一些严重的路由逻辑或至少在视图中内置到片段中的逻辑.

我想最重要的问题是:是否有一种"首选"方式可以做到这一点(比如铁轨或其他类似的食谱),还是我自己出类拔萃?

谢谢

Eug*_*ota 8

如果这确实是最好的方式(我怀疑它是),那么在数据库中映射这个的最佳方法是什么?最好保留一个"类型"列,然后将其设置为一个或另一个?

在给定场景的情况下,我认为没有明确的"最好的方法"来设计数据库结构.教科书答案是数据库规范化DRY.

三桌接近

例如,一种方法是创建包含两种类型用户的User表,仅存储公共属性,并创建具有User表外键的Student表和Provider表以及专用属性(如果有).这可能不是传统的关系数据库人所推荐的,但它更贴近OO继承模型.

一种表格方法

像你所说的另一种方法是创建一个"UserType"字段并将两种类型的用户存储到User表中.这很简单,但是你错过了利用关系数据库的引用完整性的机会.例如,如果您要创建仅针对Student的子表,例如Homework,如果学生和提供者都位于User表中,则不能简单地将外键设置为StudentID.

两张桌子接近

如果您正在使用对象关系映射框架,可能最简单的方法是将对象世界海峡中您想要的内容准确地映射到数据库中,该数据库将具有Student表和Provider表,并将两者的共性表达为特征在斯卡拉方面.

我找到了提升作弊表:

定义模型

提升或映射模型是基于具有字段的类定义的.

class WikiEntry extends KeyedMapper[Long, WikiEntry] {
  def getSingleton = WikiEntry // what's the "meta" object
  def primaryKeyField = id

  // the primary key
  object id extends MappedLongIndex(this)

  // the name of the entry
  object name extends MappedString(this, 32) {
    override def dbIndexed_? = true // indexed in the DB
  }

  object owner extends MappedLongForeignKey(this, User)

  // the text of the entry
  object entry extends MappedTextarea(this, 8192) {
    override def textareaRows  = 10
    override def textareaCols = 50
  }
}
Run Code Online (Sandbox Code Playgroud)

讨论模型的共享基本特征.

大卫波拉克写道:

你正在寻找一些Scala魔法:

trait Posting[MyType <: Mapper[MyType]] { // Defines some common fields for posted user content 
  self: MyType => 
  def primaryKeyField = id 
  object id extends MappedLongIndex(this) 
  object creator extends MappedLongForeignKey(this, User) 
  object createdAt extends MappedLong(this) { 
    override def defaultValue = System.currentTimeMillis 
  } 
} 

class FooPosting extends KeyedMapper[FooPosting] with Posting[MyType]
Run Code Online (Sandbox Code Playgroud)