使用值对象进行选择(扩展AnyVal)

时间:2016-05-04 16:35:43

标签: scala slick-2.0

我正在使用Slick 2.1.0和Scala 2.10。 我有一个值对象(EMail),我将其映射到VARCHAR列。

object EMail {
  import java.util.regex.Pattern
  val emailRegex = Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE)

  val empty = EMail("x@y.com")
}

case class EMail(value: String) extends AnyVal with MappedTo[String] {
  def isValid: Boolean = EMail.emailRegex.matcher(value).find

  def validate: EMail = {
    assert(isValid)
    EMail(value.trim.toLowerCase)
  }

  override def toString = validate.value
}

Column定义是:

def email = column[Option[EMail]]("email_address")

这是我尝试写一个发现者:

def findByEmail(email: Option[EMail]): Option[User] =
  database.withSession { implicit session: Session =>
    queryAll.filter(e => e.email.isDefined && e.email === email).firstOption
  }

这是我收到的错误消息:

[error] Users.scala:52: ambiguous implicit values: [error] both value BooleanCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[Boolean] [error] and value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[scala.slick.lifted.Column[Option[Boolean]]] [error] match expected type scala.slick.lifted.CanBeQueryCondition[Nothing] [error] queryAll.filter(_.email === email.map(_.value)).firstOption [error] ^

1 个答案:

答案 0 :(得分:1)

您不必将Option[EMail]传递给您的方法,您只需制作:

def findByEmail(email: EMail): Option[User] = {
  database.withSession { implicit session =>
    queryAll.filter(_.email === email).firstOption
  }
}

如果您确实需要Option[EMail]]作为输入参数,则应尝试以下操作:

def findByEmail(emailOpt: Option[EMail]): Option[User] = {
  emailOpt.flatMap { email =>
    database.withSession { implicit session =>
      queryAll.filter(_.email === email).firstOption
    }
  }
}