2013-05-23 5 views
0

Не могли бы вы рассказать мне, почему я не получаю внутреннее соединение, которого я ожидаю?Внутреннее соединение не работает в 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" = ?.

Как это осуществить?

Спасибо.

ответ

7

Ну, после нескольких попыток я сделал это

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

Но человек ... документация типизированного является действительно очень слаб для новичков.

+0

важно использовать, если вместо добавления его в состояние – slckin

2

Try что-то вроде:

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

BTW, вы знаете, вы можете аннотировать внешние ключи в таблице объектов правильно?

+0

Но мне не нужна какая-либо информация из «Роль» в моем случае. У меня есть id в 'some_id'. – expert

+0

Теперь я вижу, чего вы хотели. Я переписал свой запрос. – pedrofurla

+0

Да, я могу аннотировать внешние ключи, но я не уверен, что могу сделать это в моем случае с помощью Slick, потому что внешний ключ может ссылаться на разные объекты в зависимости от 'is_role'. – expert

1

Пробовал делать это в качестве комментария, чтобы Руслана ответа, но я просто не имею достаточно JEDI полномочий:

Вы можете попробовать, если это desugar-е изд версия работает?

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 }