代码之家  ›  专栏  ›  技术社区  ›  dav

创建两种不同类型的用户(scala、lift)

  •  3
  • dav  · 技术社区  · 15 年前

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

    第二个问题是如何处理视图。根据用户类型的不同,显示会有很大的不同,因此我认为会涉及一些严重的路由逻辑,或者至少在视图中的代码段中内置逻辑。

    我想最主要的问题是:有没有一个“首选”的方法来做这个(像Rails中的一个菜谱或者类似的方法),或者我有没有自己出去?

    谢谢

    1 回复  |  直到 15 年前
        1
  •  8
  •   Eugene Yokota    15 年前

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

    我认为在给定的场景下,没有明确的“最佳方法”来设计数据库结构。课本答案是 database normalization DRY .

    三表法

    例如,一种方法可以是创建包含这两种类型用户的用户表,只存储公共属性,并创建学生表和提供程序表,其中包含用户表的外键和专用属性(如果有)。这可能不是传统关系数据库人员所推荐的,但它更接近于OO继承模型。

    单表法

    如您所说的另一种方法是只创建一个“usertype”字段,并将这两种类型的用户存储到用户表中。这很简单,但是您会错过利用关系数据库的引用完整性的机会。例如,如果要创建只针对学生的子表,例如家庭作业,那么如果学生和提供者都住在用户表中,就不能简单地将外键设置为studentid。

    双表法

    如果您使用的是对象关系映射框架,那么最简单的方法可能是将对象世界海峡中您想要的东西精确映射到数据库中,该数据库将具有student表和provider表,并将两者的共性表示为scala端的特征。

    我找到电梯了 cheat sheet :

    定义模型

    Lift O-R映射模型是基于带字段的类定义的。

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

    关于拥有的讨论 shared base traits for Models .

    大卫·波拉克在书中写道:

    你在寻找斯卡拉魔法:

    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]
    
    推荐文章