Reputation: 30115
Could you please tell me why I'm not getting inner join I'm expecting to get ?
I have following tables
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 _)
}
What I'm willing to do is to fetch list of Ability
objects for particular owner (whether user or role). So following documentation I wrote following join query for it
val some_id = role.id
val q2 = for {
a <- Abilities
rel <- AbilitiesMapping
if rel.owner_id === some_id.bind
} yield (a)
But q2.selectStatement
returns absolutely wrong query for it. Which is select x2."id", x2."is_can", x2."verb", x2."subject", x2."context" from "abilities" x2, "abilities_mapping" x3 where x3."owner_id" = ?
in my case.
How should it be implemented?
Thanks.
Upvotes: 0
Views: 2841
Reputation: 652
Tried doing this as a comment to ruslan's answer, but I just dont have enough jedi powers:
Can you try if this desugar-ed version works?
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 }
Upvotes: 1
Reputation: 12783
Try something like:
val q2 = for {
a <- Abilities
rel <- AbilitiesMapping
if a.id == rel.obj_id && rel.owner_id === some_id.bind
} yield (a)
BTW, you know you can annotate your foreign keys in the Table objects right?
Upvotes: 2
Reputation: 30115
Well, after multiple attempts I made it
val innerJoin = for {
(a, rel) <- Abilities innerJoin AbilitiesMapping on (_.id === _.obj_id) if rel.owner_id === some_id.bind
} yield a
But man... typesafe's documentation is really really weak for newcomers.
Upvotes: 10