Scala + Slick + Accord - 自定义值 class 类型不起作用。只是一个糟糕的方法?
Scala + Slick + Accord - Custom value class types not working. Just a bad approach?
我对 Scala 还是很陌生,正在考虑使用 Slick。
我也在查看 Accord (github.com/wix/accord) 进行验证。
Accord 的验证似乎是针对整个对象的,但我希望能够为字段类型定义验证器,所以我想到了使用值 类 来使用类型别名,这样我就可以轻松在使用这些字段类型的各种情况 类 中重复使用验证。
因此,我定义了以下内容:
object FieldTypes {
implicit class ID(val i: Int) extends AnyVal
implicit class UserPassword(val s: String) extends AnyVal
implicit class Email(val s: String) extends AnyVal
implicit class Name(val s: String) extends AnyVal
implicit class OrgName(val s: String) extends AnyVal
implicit class OrgAlias(val s: String) extends AnyVal
}
package object validators {
implicit val passwordValidator = validator[UserPassword] { _.length is between(8,255) }
implicit val emailValidator = validator[Email] { _ is notEmpty }
implicit val nameValidator = validator[Name] { _ is notEmpty }
implicit val orgNameValidator = validator[OrgName] { _ is notEmpty }
implicit val teamNameValidator = validator[TeamName] { _ is notEmpty }
}
case object Records {
import FieldTypes._
case class OrganizationRecord(id: ID, uuid: UUID, name: OrgName, alias: OrgAlias)
case class UserRecord(id: ID, uuid: UUID, email: Email, password: UserPassword, name: Name)
case class UserToOrganizationRecord(userId: ID, organizationId: ID)
}
class Tables(implicit val p: JdbcProfile) {
import FieldTypes._
import p.api._
implicit object JodaMapping extends GenericJodaSupport(p)
case class LiftedOrganizationRecord(id: Rep[ID], uuid: Rep[UUID], name: Rep[OrgName], alias: Rep[OrgAlias])
implicit object OrganizationRecordShape extends CaseClassShape(LiftedOrganizationRecord.tupled, OrganizationRecord.tupled)
class Organizations(tag: Tag) extends Table[OrganizationRecord](tag, "organizations") {
def id = column[ID]("id", O.PrimaryKey)
def uuid = column[UUID]("uuid", O.Length(36, varying=false))
def name = column[OrgName]("name", O.Length(32, varying=true))
def alias = column[OrgAlias]("alias", O.Length(32, varying=true))
def * = LiftedOrganizationRecord(id, uuid, name, alias)
}
val organizations = TableQuery[Organizations]
}
不幸的是,我显然误解或高估了 Scala 隐式转换的强大功能。我的 passwordValidator
似乎没有意识到 length
属性 到 UserPassword
和我的 Organizations
[=34] 上的 *
声明=] 似乎不认为它符合 LiftedOrganizationRecord
.
中定义的形状
总的来说,我只是在做一些非常愚蠢的事情吗?我什至不应该尝试使用这些类型的自定义类型,而是简单地使用标准类型,以更好的方式定义我的验证器吗?或者这是一种好的做事方式,但我只是忘记了一些简单的事情?
如有任何建议,我们将不胜感激!
感谢 scala gitter 频道的一些帮助,我意识到核心错误是对价值转换方向的误解 类。我理解为 ValueClass -> WrappedValueType,但实际上是 WrappedValueType -> ValueClass。因此,例如,Slick 没有将 ID 视为 Int。
我对 Scala 还是很陌生,正在考虑使用 Slick。
我也在查看 Accord (github.com/wix/accord) 进行验证。
Accord 的验证似乎是针对整个对象的,但我希望能够为字段类型定义验证器,所以我想到了使用值 类 来使用类型别名,这样我就可以轻松在使用这些字段类型的各种情况 类 中重复使用验证。
因此,我定义了以下内容:
object FieldTypes {
implicit class ID(val i: Int) extends AnyVal
implicit class UserPassword(val s: String) extends AnyVal
implicit class Email(val s: String) extends AnyVal
implicit class Name(val s: String) extends AnyVal
implicit class OrgName(val s: String) extends AnyVal
implicit class OrgAlias(val s: String) extends AnyVal
}
package object validators {
implicit val passwordValidator = validator[UserPassword] { _.length is between(8,255) }
implicit val emailValidator = validator[Email] { _ is notEmpty }
implicit val nameValidator = validator[Name] { _ is notEmpty }
implicit val orgNameValidator = validator[OrgName] { _ is notEmpty }
implicit val teamNameValidator = validator[TeamName] { _ is notEmpty }
}
case object Records {
import FieldTypes._
case class OrganizationRecord(id: ID, uuid: UUID, name: OrgName, alias: OrgAlias)
case class UserRecord(id: ID, uuid: UUID, email: Email, password: UserPassword, name: Name)
case class UserToOrganizationRecord(userId: ID, organizationId: ID)
}
class Tables(implicit val p: JdbcProfile) {
import FieldTypes._
import p.api._
implicit object JodaMapping extends GenericJodaSupport(p)
case class LiftedOrganizationRecord(id: Rep[ID], uuid: Rep[UUID], name: Rep[OrgName], alias: Rep[OrgAlias])
implicit object OrganizationRecordShape extends CaseClassShape(LiftedOrganizationRecord.tupled, OrganizationRecord.tupled)
class Organizations(tag: Tag) extends Table[OrganizationRecord](tag, "organizations") {
def id = column[ID]("id", O.PrimaryKey)
def uuid = column[UUID]("uuid", O.Length(36, varying=false))
def name = column[OrgName]("name", O.Length(32, varying=true))
def alias = column[OrgAlias]("alias", O.Length(32, varying=true))
def * = LiftedOrganizationRecord(id, uuid, name, alias)
}
val organizations = TableQuery[Organizations]
}
不幸的是,我显然误解或高估了 Scala 隐式转换的强大功能。我的 passwordValidator
似乎没有意识到 length
属性 到 UserPassword
和我的 Organizations
[=34] 上的 *
声明=] 似乎不认为它符合 LiftedOrganizationRecord
.
总的来说,我只是在做一些非常愚蠢的事情吗?我什至不应该尝试使用这些类型的自定义类型,而是简单地使用标准类型,以更好的方式定义我的验证器吗?或者这是一种好的做事方式,但我只是忘记了一些简单的事情?
如有任何建议,我们将不胜感激!
感谢 scala gitter 频道的一些帮助,我意识到核心错误是对价值转换方向的误解 类。我理解为 ValueClass -> WrappedValueType,但实际上是 WrappedValueType -> ValueClass。因此,例如,Slick 没有将 ID 视为 Int。