Создание двух разных типов пользователей (Scala, Lift) - PullRequest
3 голосов
/ 02 октября 2009

Я создаю веб-сайт, для которого потребуются пользователи двух типов: студенты и поставщики. В традиционной настройке Java я бы создал пользовательский класс (или интерфейс), а затем создал два класса, которые унаследованы от пользователя. Является ли это лучшим курсом в scala, с использованием модификаторов "extends" и "with"? Если это действительно лучший способ (который, я подозреваю, так и есть), то какой лучший способ отобразить это в БД? Было бы лучше сохранить столбец типа, а затем установить один или другой?

Второй вопрос - как работать с видом. Дисплей будет сильно отличаться в зависимости от типа пользователя, и поэтому я полагаю, что будет задействована серьезная логика маршрутизации или, по крайней мере, логика, встроенная в фрагменты вида.

Я думаю, что главный вопрос: есть ли "предпочтительный" способ сделать это (например, рецепт в рельсах или что-то подобное), или я вроде как один?

Спасибо

1 Ответ

8 голосов
/ 03 октября 2009

Если это действительно лучший способ (что, я подозреваю, так и есть), какой лучший способ отобразить это в БД? Было бы лучше сохранить столбец «type», а затем установить его на один или другой?

Я не думаю, что существует ясный "лучший способ" для проектирования структуры базы данных с учетом сценария. Ответ учебника: нормализация базы данных и DRY .

Подход с тремя столами

Одним из способов, например, может быть создание таблицы User, содержащей оба типа пользователей, с сохранением только общих атрибутов, и создание таблицы Student и таблицы Provider с внешним ключом для таблицы User и специализированными атрибутами, если таковые имеются. Вероятно, это не то, что рекомендовал бы специалист по традиционной реляционной базе данных, но оно сопоставляется с моделью наследования ОО.

Подход к одному столу

Другой подход, как вы сказали, состоит в том, чтобы просто создать поле "UserType" и сохранить пользователей обоих типов в таблице User. Это просто, но вы упускаете возможность воспользоваться ссылочной целостностью реляционной базы данных. Например, если вам нужно было создать дочернюю таблицу, специфичную только для ученика, например, домашнюю работу, вы не можете просто сделать внешний ключ для StudentID, если в таблице User проживают и ученики, и провайдеры.

Подход к двум столам

Если вы используете инфраструктуру объектно-реляционного сопоставления, вероятно, самый простой способ - это отобразить именно то, что вы хотите в проливе объектного мира, в базу данных, которая будет иметь таблицу Student и таблицу Provider, и выразить общность две черты в стороне Скалы.

Я нашел Lift шпаргалка :

Определение моделей

сопоставленные модели 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
  }
}

Обсуждение наличия общих черт для моделей .

В теме Дэвид Поллак пишет:

Вам нужна магия Скалы:

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]
...