内部联接在Slick中不起作用

时间:2013-05-23 06:51:07

标签: scala scala-2.10 slick

你能告诉我为什么我没有得到内心的加入我期待得到吗?

我有以下表格

case class Ability(id: UUID, can: Boolean, verb: String, subject: String, context: String)

object Abilities extends Table[Ability]("abilities"){
  def id = column[UUID]("id", O.PrimaryKey)
  def can = column[Boolean]("is_can")
  def verb = column[String]("verb")
  def subject = column[String]("subject")
  def context = column[String]("context")

  def * = id ~ can ~ verb ~ subject ~ context <> (Ability, Ability.unapply _)
}

case class Role(id: UUID, name : String)

object Roles extends Table[Role]("roles"){
  def id = column[UUID]("id", O.PrimaryKey)
  def name = column[String]("name")

  def * = id ~ name <> (Role, Role.unapply _)
}

// And join table
case class AbilityRelationship(owner_id: UUID, obj_id: UUID, is_role: Boolean)

object AbilitiesMapping extends Table[AbilityRelationship]("abilities_mapping"){
  def owner_id = column[UUID]("owner_id")
  def obj_id = column[UUID]("obj_id")
  def is_role = column[Boolean]("is_role")

  def * = owner_id ~ obj_id ~ is_role <> (AbilityRelationship, AbilityRelationship.unapply _)
}

我愿意做的是为特定所有者(无论是用户还是角色)获取Ability个对象的列表。所以我按照文档编写了以下连接查询

val some_id = role.id
val q2 = for {
  a <- Abilities
  rel <- AbilitiesMapping
  if rel.owner_id === some_id.bind
} yield (a)

q2.selectStatement返回绝对错误的查询。在我的情况下,这是select x2."id", x2."is_can", x2."verb", x2."subject", x2."context" from "abilities" x2, "abilities_mapping" x3 where x3."owner_id" = ?

应该如何实施?

感谢。

3 个答案:

答案 0 :(得分:8)

好吧,经过多次尝试我做到了

  val innerJoin = for {
    (a, rel) <- Abilities innerJoin AbilitiesMapping on (_.id === _.obj_id) if rel.owner_id === some_id.bind
  } yield a

但是男人...... typesafe的文档确实对新手来说真的很弱。

答案 1 :(得分:2)

尝试类似:

val q2 = for {
  a <- Abilities
  rel <- AbilitiesMapping
  if a.id == rel.obj_id && rel.owner_id === some_id.bind
} yield (a)

顺便说一句,你知道你可以在Table对象中注释你的外键吗?

答案 2 :(得分:1)

尝试这样做是对鲁斯兰答案的评论,但我没有足够的绝地权力:

你可以尝试一下这个desugar-ed版本吗?

val rightSide = AbilitiesMapping.filter(_.owner_id === some_id)    
val innerJoin = (Abilities innerJoin (rightSide) on (
  (l,r) => (l.id === r.obj_id)
).map { case (l, r) => l }