Reputation: 57
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
Upvotes: 1
Views: 383
Reputation: 43310
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 ]
Upvotes: 2