考虑以下两个模型和一个GET /articles/:slug/comments
请求,我想检索属于一篇文章的评论,基于它的slug
.
Article json sql=articles
slug Slug
title Text
description Text
body Text
createdAt UTCTime default=now()
updatedAt UTCTime Maybe default=NULL
userId UserId
UniqueSlug slug
Comment json sql=comments
body Text
createdAt UTCTime default=now()
updatedAt UTCTime Maybe default=NULL
articleId ArticleId
userId UserId
使用persistence's rawSql
,我们可以如下完成
getCommentsForArticle :: Slug -> App (Cmts [Entity Comment])
getCommentsForArticle slug = do
comments <- runDb $ rawSql stm [toPersistValue slug]
return (Cmts comments)
where stm = "SELECT ?? FROM comments \
\WHERE article_id IN (\
\SELECT id FROM articles WHERE slug = ?)"
但是,鉴于我想维护 Haskell 和 SQL 之间的类型安全,我想使用esqueleto
. 这是我正在努力的部分。通过阅读文档,sub_select似乎是完成这项工作的工具。这是我所拥有的:
getCommentsForArticle :: Slug -> App (Cmts [Comment])
getCommentsForArticle slug = do
comments <- E.select $
E.from $ \cmts -> do
let subQuery =
E.from $ \arts -> do
E.where_ $ arts ^. ArticleSlug ==. E.val slug
return (arts ^. ArticleId)
E.where_ $ cmts ^. CommentArticleId ==. E.sub_select subQuery
return cmts
return $ Cmts comments
我也注意到in_ 运算符,但我不知道如何使用它,也不知道它是否比sub_select更合适。
我错过了什么?语法是否正确?谢谢。