I have the following classes:
case class Product( title : String, description: String, contract: Contract)
case class Contract(contractType: ContractType, price: Int )
case class ContractType(description: String)
and these DTOs:
case class ProductDto(id: Long, title: String, description: String, contractType: ContractTypeDto, price: Int)
case class ContractTypeDto(id: Long, description: String)
I need to create a method that returns the list of products but with the data filled in DTOs, something like this:
def list = Db.query[Product].fetch().toList.map(x => ProductDto(x.id, x.title,
x.description, ContractTypeDto(x.contract.contractType.id,
x.contract.contractType.description), x.contract.price))
The thing is that I can't access to the x.contract.contractType.id but SORM allows me to access to x.id
(at first level), there is any way to do it??
Thanks
You can always access the id
using casting if you have to:
x.contract.contractType.asInstanceOf[ sorm.Persisted ].id
It is cleaner though to utilize pattern matching to produce a total function to do it:
def asPersisted[ A ]( a : A ) : Option[ A with sorm.Persisted ]
= a match {
case a : A with sorm.Persisted => Some( a )
case _ => None
}
Then we can use it like so:
asPersisted( x.contract.contractType ).map( _.id ) // produces Option[ Long ]
The benefit of the total approach is that you protect yourself from runtime casting exceptions, which will arise if you try to cast a non-persisted value.
You can also "pimp" asPersisted
as a method onto Any
using value-classes if you don't find this disturbing:
implicit class AnyAsPersisted[ A ]( val a : A ) extends AnyVal {
def asPersisted : Option[ A with sorm.Persisted ]
= a match {
case a : A with sorm.Persisted => Some( a )
case _ => None
}
}
Then you'll be able to use it like so:
x.contract.contractType.asPersisted.map( _.id ) // produces Option[ Long ]