2017-05-28 10 views
3

次の2つのモデルとGET /articles/:slug/commentsリクエストを考慮して、記事に属するコメントを、slugに基づいて取得したいと考えています。持続性のrawSqlを使用してEsqueletoを使用して "SELECT ... IN(SELECT ...)"を行うには?

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 

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_ operatorに気づいたが、私はそれを使用する方法を見つけ出すことはできませんまたそれがsub_selectよりも適切である場合。

私には何が欠けていますか?構文は正しいですか?ありがとう。

+0

関連のないような何かをしたいが、 'SELECT * ...' :)悪いスタイルですよ。なぜSQLiteやその他のSQLデータベースを使用しないのですか?彼らはすべて型付きが良いです;) – Igor

+0

@Igor悪いスタイルでは、必要なものだけを選択しないという意味ですか?あなたの2番目の質問として、私は 'postgresql'で' persistent'を使っていると指定するために質問を編集しました。 –

+0

うん。 SQLが必要なときにSQLだけを使用するのはなぜですか? – Igor

答えて

0

あなたはこの

getCommentsForArticle slug = do 
    c <- select $ from $ \cmts -> do 
     let a = subList_select from $ \arts -> do 
       where_ $ arts ^. ArticleSlug ==. val slug 
       return $ arts ^. ArticleId 
     where_ $ cmts ^. CommentArticleId `in_` a 
     return cmts 
    return $ Cmts c 
関連する問題