Yesod получить отношения один ко многим из базы данных

У меня две таблицы product а также category определяется как ниже:

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

Я хотел бы извлечь из базы данных список типов [(Category, [Product])], Как мне поступить об этом в Йесоде?

Я совершенно новичок и целый день искал, пытаясь найти что-то для этого.

Обновить

Это моя деревня

$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)
Другие вопросы по тегам