polymorphic components
Let’s say that on our blogging site, we want to be able to verify the identity of our users, and we have a few different approaches for doing so. We can use email verification, where we send the user an email, with a link that they can click to verify the email address. We can also use SMS verification, where we send the user an SMS message with a temporary code in it, and ask the user to enter it into the webpage. Or we can use a third-party account verification system such as Google Sign-In.
An idealized representation of this portion of our domain might look like so:
import org.joda.time.DateTime
trait UserVerification {
val verificationDate: DateTime
}
case class EmailVerification(
email: Email,
verificationDate: DateTime)
extends UserVerification
case class SmsVerification(
phoneNumber: PhoneNumber,
verificationDate: DateTime)
extends UserVerification
case class GoogleSignIn(
email: Email,
idToken: String,
verificationDate: DateTime)
extends UserVerification
In our User
object, we want to keep track of all the user’s
successful verification attempts:
case class User(
username: String,
email: Email,
verifications: List[UserVerification])
For this to work, all we need to do is to make longevity aware of our
polymorphic component UserVerification
, and its children. We do this
using annotations @polyComponent
and @derivedComponent
:
import longevity.model.annotations.polyComponent
import longevity.model.annotations.derivedComponent
import longevity.model.annotations.persistent
import org.joda.time.DateTime
@polyComponent[DomainModel]
trait UserVerification {
val verificationDate: DateTime
}
@derivedComponent[DomainModel, UserVerification]
case class EmailVerification(
email: Email,
verificationDate: DateTime)
extends UserVerification
@derivedComponent[DomainModel, UserVerification]
case class SmsVerification(
phoneNumber: PhoneNumber,
verificationDate: DateTime)
extends UserVerification
@derivedComponent[DomainModel, UserVerification]
case class GoogleSignIn(
email: Email,
idToken: String,
verificationDate: DateTime)
extends UserVerification
@persistent[DomainModel]
case class User(
username: String,
email: Email,
verifications: List[UserVerification])
The non-annotation equivalent is as follows:
import longevity.model.DerivedCType
import longevity.model.PType
import longevity.model.PolyCType
import org.joda.time.DateTime
trait UserVerification {
val verificationDate: DateTime
}
object UserVerification extends PolyCType[DomainModel, UserVerification]
case class EmailVerification(
email: Email,
verificationDate: DateTime)
extends UserVerification
object EmailVerification extends DerivedCType[DomainModel, EmailVerification, UserVerification]
case class SmsVerification(
phoneNumber: PhoneNumber,
verificationDate: DateTime)
extends UserVerification
object SmsVerification extends DerivedCType[DomainModel, SmsVerification, UserVerification]
case class GoogleSignIn(
email: Email,
idToken: String,
verificationDate: DateTime)
extends UserVerification
object GoogleSignIn extends DerivedCType[DomainModel, GoogleSignIn, UserVerification]
case class User(
username: String,
email: Email,
verifications: List[UserVerification])
object User extends PType[DomainModel, User] {
object props {
// ...
}
}