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

发布于 2024-08-07 10:14:09 字数 333 浏览 4 评论 0原文

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

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

我想最重要的问题是:是否有一种“首选”方法可以做到这一点(例如 Rails 中的食谱或类似方法),或者我是否有点独自一人?

谢谢

I am creating a website which will need two types of users: students and providers. In a traditional java setting I would create a user class (or interface) and then create two classes which inherited from the user. Is this the best course in scala too, using the "extends" and "with" modifiers? If that is indeed the best way (which I suspect it is), what the best way to map this in the DB? Would it be best to keep a "type" column and then have it set to one or the other?

The second question is how to work with the view. The display will be very different depending on which type of user one is and so I figure there will be some serious routing logic involved or at least logic built into snippets in the view.

I guess the overarching question is: Is there a "preferred" way to go about doing this (like a recipe in rails or some such), or am I kind of out on my own?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

戏剧牡丹亭 2024-08-14 10:14:09

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

我认为在给定的场景下,没有明确的“最佳方法”来设计数据库结构。教科书的答案是数据库规范化

三表方法

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

一种表方法

像您所说的另一种方法是仅创建一个“UserType”字段并将两种类型的用户存储到用户表中。这很简单,但是您会错过利用关系数据库的引用完整性的机会。例如,如果您要创建仅针对学生的子表(例如家庭作业),并且学生和提供者都位于用户表中,则不能简单地为 StudentID 创建外键。

两个表方法

如果您使用对象关系映射框架,可能最简单的方法是将对象世界中您想要的内容精确映射到数据库中,这将具有 Student 表和 Provider 表,并表达两个作为 Scala 方面的特征。

我发现 Lift 备忘单

定义模型

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

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

讨论模型的共享基本特征

大卫·波拉克 (David Pollak) 在帖子中写道:

您正在寻找一些 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]

If that is indeed the best way (which I suspect it is), what the best way to map this in the DB? Would it be best to keep a "type" column and then have it set to one or the other?

I don't think there is clear "the best way" to design database structure given a scenario. The text book answer is database normalization and DRY.

Three tables approach

One way for instance could be to create User table containing both types of users, storing only the common attributes, and create Student table and Provider table with foreign key to User table and specialized attributes if any. This probably is not what a traditional relational database person would recommend, but it maps closer to the OO inheritance model.

One table approach

Another approach like you said would be to just create a "UserType" field and store both types of users into User table. It's simple, but you then miss the opportunity to take advantage of the referential integrity of the relational database. For example, if you were to create child table specific only to Student, such as Homework, you can't simply make foreign key to StudentID if both students and providers lived in User table.

Two tables approach

If you are using Object-Relational Mapping framework, likely the easiest way to go is to map exactly what you want in the object world strait into the database, which would be having Student table and Provider table, and express the commonality of two as trait in Scala side.

I found Lift cheat sheet:

Defining Models

lift O-R mapped models are defined based on a class with fields.

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

Discussion on having shared base traits for Models.

In the thread David Pollak writes:

You're looking for some Scala magic:

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]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文