2015-10-27 43 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

我已经添加了哈姆雷特我的问题。谢谢。 –