aselab / scala-activerecord

ActiveRecord-like ORM library for Scala
MIT License
322 stars 31 forks source link

how to handle inheritance? #59

Closed ehudkaldor closed 9 years ago

ehudkaldor commented 9 years ago

if i want to have inheritance in my models, like such: case class Person case class Student extends Person case class Teacher extends Person

how would i do that? i would prefer to have straightforward inheritance, like in RDBMS - Person is a table, and Student and Teacher are tables with foreign keys on Person. can i do that? another option would be for Teacher and Student to have a Person member to hold that portion, but then what would the reverse reference (belongsTo?) point to?

y-yoshinoya commented 9 years ago

Thank you for your feedback. Sorry to be slow to reply.

Currently, does not support the single-table inheritance(#17) in the library, can not be coded as described above.

As an alternative, I will show two ways:

By Association

package models

import com.github.aselab.activerecord._
import com.github.aselab.activerecord.dsl._

object Tables extends ActiveRecordTables {
  val jobs = table[Job]
  val people = table[Person]
}

case class Job(name: String) extends ActiveRecord {
  lazy val people = hasMany[Person]
}

object Job extends ActiveRecordCompanion[Job] {
  def student: Job = this.findByOrCreate(Job("student"), "name")
  def teacher: Job = this.findByOrCreate(Job("teacher"), "name")
}

case class Person(name: String, age: Int) extends ActiveRecord {
  val jobId: Option[Long] = None
  lazy val job = belongsTo[Job]
}

object Person extends ActiveRecordCompanion[Person] {
  def students = Job.student.people
  def teachers = Job.teacher.people
}

object App extends App {
  Tables.initailize

  val p = Person("Alice", 20)
  p.job := Job.teacher
  p.save

  Person.teachers.toList        // List(Person("Alice", 20))

  Tables.cleanup
}

By Enumeration

package models

import com.github.aselab.activerecord._
import com.github.aselab.activerecord.dsl._

object Tables extends ActiveRecordTables {
  val people = table[Person]
}

object Job extends Enumeration {
  val Teacher, Student = Value
}

case class Person(name: String, age: Int, job: Job.Value) extends ActiveRecord {
  def this() = this("", 0, Job.Student)
}

object Person extends ActiveRecordCompanion[Person] {
  def students = this.where(_.job === Job.Student)
  def teachers = this.where(_.job === Job.Teacher)
}

object App extends App {
  Tables.initailize

  Person("Alice", 20, Job.Teacher).save

  Person.teachers.toList         // List(Person("Alice", 20, Job.Teacher))

  Tables.cleanup
}