我试图让selectOneMany在有限的成功下工作。
我有以下数据库模型
User
email Text
verkey Text Maybe
verified Bool
password Text Maybe
UniqueUser email
date UTCTime
deriving Show
Competence
parent CompetenceId Maybe
title Text
UniqueCompetence title
deriving Show Read
UserCompetence
competence CompetenceId
user UserId Eq
UniqueUserCompetence user competence
deriving Show Read
来自我的处理程序的代码
mmember <- runMaybeT $ do
id <- MaybeT $ maybeAuth
user <- MaybeT . runDB . get . entityKey $ id
Entity memberId member <- MaybeT . runDB . getBy . UniqueMember . userEmail $ user
competences <- lift . runDB . runJoin $ (selectOneMany (UserCompetenceUser <-.) userCompetenceUser)
return (member,competences)
第一个;我无法在没有添加大类型签名的情况下运行此代码,这应该是它吗?
competences <- lift . runDB . runJoin $ (selectOneMany (UserCompetenceUser <-.) userCompetenceUser :: SelectOneMany SqlPersist (UserGeneric SqlPersist) (UserCompetenceGeneric SqlPersist))
其次;什么是能力类型。理想情况下,我希望最终获得[实体能力的能力]。
最后;如何为上述联接添加过滤器,以便仅获得“用户”的权限?
答案 0 :(得分:2)
我已经告诉过你,由于SelectOneMany
使用的类型别名可能不是归纳的,因此无法避免额外的类型签名;即你的代码试图比它应该更多态,并且类型签名是限制多态性所必需的。
您可以通过“从不同的角度”约束类型来避免使用巨大的签名,例如:
return (member, competences :: [(Entity User, [Entity UserCompetence])])
由于类型别名User
和UserCompetence
选择了特定的数据库后端,因此应该适当地解析类型。
另外,我只是为你破坏了competences
的类型。哈!我希望这对你来说已经足够了。如果你想直接进行多对多三表连接,以便你可以获得用户“拥有”的所有权限,你应该使用预备语句,因为可能存在AST开销,所以请查看the generic raw SQL interface哪个让您可以使用您可能更习惯使用的传统"SELECT * FROM foo WHERE bar = ?" [filteredBarValue]
;它不提供与persistent
的其余部分相同的类型安全性,但我认为这是在您的情况下实现三表连接的最简单方法。
您可以通过修改类型为User
的{{1}}的结果来限制所选的oneFilterMany
。像这样(没有测试过,但应该工作):
OneFilterMany
答案 1 :(得分:2)
感谢来自dflemstr的(很多)帮助,我最终得到了
mmember <- runMaybeT $ do
id <- MaybeT $ maybeAuth
let user = entityVal id
Entity memberId member <- MaybeT . runDB . getBy . UniqueMember . userEmail $ user
let competenceStatement =
Text.concat
[ "SELECT ?? "
, "FROM competence, user_competence "
, "WHERE competence.id = user_competence.competence_id "
, "AND ? = user_competence.user_id"
]
competences <- lift . runDB $ rawSql competenceStatement
[toPersistValue . entityKey $ id]
return (member, competences :: [Entity Competence])