I was trying to implement some Model - Row implementation similar that Rails (Activerecord) in Scala. I simply trying to do this;
trait Model[A]:
def query = "model has this good stuff I want to use in RowData"
trait RowData[B <: Model[B]]:
def query = B.query
case class Person(name: String, age: Int) extends RowData[Person]
object Person extends Model[Person]
Person("onur", 38).query // I wan't to use like this
I'm getting Not found: B on RowData
trait. Because Model[A]
is an object I supposed that I can use it as is.
You can try in here: https://scastie.scala-lang.org/U3MOJhFXSS2O8fanY5aIpg
It seems the requirement is to use the companion object's method, but the issue with this solution is that, given this code:
trait RowData[B <: Model[B]]:
def query = B.query
Because B
is supposed to be the companion object, it cannot be passed as a type in []
. You need to pass it as an object in parentheses ()
, like this:
trait Model[A]:
def query = "model has this good stuff I want to use in RowData"
trait RowData(B: Model[_]):
def query = B.query
case class Person(name: String, age: Int) extends RowData(Person)
object Person extends Model[Person]
Person("onur", 38).query
However, this is not an ideal solution either, because B
is not enforced to be the companion object you pass for the RowData
trait. In Scala, we commonly use Context Bound to enforce this, like this:
trait Model[A]:
def query = "model has this good stuff I want to use in RowData"
trait RowData[B : Model]:
def query = summon[Model[B]].query
case class Person(name: String, age: Int) extends RowData[Person]
given Person: Model[Person] with {} // Implement custom query method here
Person("onur", 38).query