Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: constructor method with Option

Tags:

oop

orm

scala

Avoiding usual ORM for non-relevant reasons, I'm trying to write a class that can both present data from DB and add/update data to it (is this a good idea in the first place?).

class Car (val _id:ID, val _name:String = "") {
    def this(_id:ID) = {
        val car = DB.fetchCar(_id)
        this(_id,car.name)
    } 
    def this(_name:String) = this(null,_name)
    def isSynced:Boolean = { ... }
    def sync { ... }
}

This means you can:

  1. knowing both id and name of a record, create an object representing it,
  2. knowing only the record's id, you can construct the rep object from DB and
  3. if you do not provide an id, your object will be in an unsynced state and will get synced after an add/update happens.

The thing is, the 1st constructor depends on a DB operation, thus Option[Car] as return type makes more sense. But as far as I can see Scala doesn't allow you to do something like:

def this(_id:ID):Option[Car] = { 
   try {
      val car = DB.fetchCar(_id)
      Some(this(_id,car.name))
   } catch {
      case e:Exception => None
   } 
}

Does this make sense? How would you implement this?

like image 576
parsa Avatar asked Feb 03 '26 03:02

parsa


1 Answers

You can do it from the companion object of your class:

class Car private (data: CarData) {
    ...
}

object Car {

    def apply(id: Int): Option[Car] = {
        DB.find(id) match {
            case Some(data) => Some(new Car(data))
            case _ => None
        }
    }

    def apply(data: CarData): Car = {
        new Car(data)
    }
}

This allows client code to

val someId: Int = ...
val maybeCar = Car(someId)              // Will be Option[Car]
val someKnownData: CarData = ...
val definitiveCar = Car(someKnownData)  // Will be Car
like image 159
Dirk Avatar answered Feb 04 '26 18:02

Dirk