2015-10-27 59 views
2

一對多的關係我有兩個表productcategory像定義如下:耶索德得到一個從數據庫

Product 
    category CategoryId 
    name Text 
    description Text 
    price Int 
Category 
    name Text 

我想從數據庫中提取[(Category, [Product])]類型的列表。在Yesod中我會怎麼做呢?

我是一個全新的人,已經找了好幾天的時間試圖找到一些東西來做到這一點。

更新

這是我的小村莊

$if null rows 
    <p>No products 
$else 
    <div class="list-group menu"> 
    $forall (category, [products]) <- rows 
     <div class="list-group-item"> 
     <h4 class="list-group-item-heading">#{categoryName category} 

     $forall product <- products 
     <div class="list-group-item"> 
     <div class="container-fluid"> 
      <div class="col-sm-10"> 
      <p>#{productName product} - #{productPrice product}</p> 
      <div class="col-md-2 text-right"> 
      <div class="btn-group"> 
       <a class="btn btn-default btn-xs"><div class="glyphicon glyphicon-plus"></div></a> 
       <a class="btn btn-default btn-xs"><div class="glyphicon glyphicon-minus"></div></a> 

回答

1

的兩種基本方法是:

  1. 獲取所有類別的列表,然後爲每個類別,得到產品列表
  2. 使用esqueleto進行內部(或左側)連接,然後使用排序和分組功能在Haskell

第一種方法可能更簡單。這裏有一個例子:

{-# LANGUAGE EmptyDataDecls    #-} 
{-# LANGUAGE FlexibleContexts   #-} 
{-# LANGUAGE GADTs      #-} 
{-# LANGUAGE GeneralizedNewtypeDeriving #-} 
{-# LANGUAGE MultiParamTypeClasses  #-} 
{-# LANGUAGE OverloadedStrings   #-} 
{-# LANGUAGE QuasiQuotes    #-} 
{-# LANGUAGE TemplateHaskell   #-} 
{-# LANGUAGE TypeFamilies    #-} 
import   Control.Monad.IO.Class (liftIO) 
import   Database.Persist 
import   Database.Persist.Sqlite 
import   Database.Persist.TH 
import Data.Text (Text) 
import Control.Monad (forM) 

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| 
Product 
    category CategoryId 
    name Text 
    description Text 
    price Int 
    deriving Show 
Category 
    name Text 
    deriving Show 
|] 

main :: IO() 
main = runSqlite ":memory:" $ do 
    runMigrationSilent migrateAll 
    populate 
    res <- query 
    liftIO $ print res 

populate = do 
    watches <- insert $ Category "Watches" 
    insert_ $ Product watches "Rolex" "Fancy" 100 
    insert_ $ Product watches "Limex" "Cheap" 2 

    computers <- insert $ Category "Computers" 
    insert_ $ Product computers "MacBook Air" "Apple" 1500 

query = do 
    cats <- selectList [] [Asc CategoryName] 
    forM cats $ \(Entity catId cat) -> do 
     products <- selectList 
      [ProductCategory ==. catId] 
      [Asc ProductName] 
     return (cat, map entityVal products) 
+0

謝謝邁克爾。我認爲這是行得通的。我唯一的問題是,在我的小村莊,我試圖循環查看列表,並且它說'無法將'產品'類型與't0產品'匹配。你知道那是什麼嗎?或者你需要更多的信息來回答這個問題?再次感謝。 –

+0

當你實際需要兩個(外部和內部列表)時,聽起來像你正在使用一個。但我不能確定沒有看到你的小村落 –

+0

我已經添加了哈姆雷特我的問題。謝謝。 –