繁体   English   中英

从数据库中检索消化函子的选择列表(捕捉/抢劫)

[英]Retrieving a list of choices for Digestive Functors from the database (Snap/Heist)

我有一个地址表,可以处理添加和编辑(添加时不显示任何内容,编辑时仅显示地址)。 到现在为止,我已经对州和国家/地区的选择进行了硬编码,并带有少量项目。

addressForm :: Monad m => Maybe Address -> [Address] -> Form Text m Address
addressForm a addrs = 
    Address
        <$> "id" .: choiceWith (addrToChoice addrs) (fmap id a)
        <*> "name" .: string (fmap name a)
        <*> "street" .: string (fmap street a)
        <*> "city" .: string (fmap city a)
        <*> "state" .: choiceWith stateChoices (fmap state a)
        <*> "country" .: choiceWith countryChoicesRequired (fmap country a)
        <*> "zipcode" .: string (fmap zipcode a)


stateChoices :: [(Text, (Maybe String, Text))] -- (htmlValue, (realValue, labelValue))
stateChoices = [("ON", (Just "ON", "Ontario")), ("NE", (Just "NE", "Nebraska"))]

countryChoicesRequired :: [(Text, (String, Text))]
countryChoicesRequired = [("CA", ("CA", "Canada")), ("US", ("US", "United States of America"))]

现在,我想从数据库中检索州和国家/地区的列表。 我可以将州/国家/地区列表传递给表单,就像我已经在处理地址列表一样,但是此表单还是3或4种其他表单(新广告客户表单,新客户表单等)的子表单。而且我不需要像表格中的地址列表那样的表格以外的州/国家列表。

这是我刚刚添加的用于获取国家/地区信息的新表格:

addressForm' :: (HasPostgres p, Monad m) => Maybe Address -> [Address] -> p (Form Text m Address)
addressForm' a addrs = do
    countries <- countryChoices'
    return $ Address
        <$> "id" .: choiceWith (addrToChoice addrs) (fmap id a)
        <*> "name" .: string (fmap name a)
        <*> "street" .: string (fmap street a)
        <*> "city" .: string (fmap city a)
        <*> "state" .: choiceWith stateChoices (fmap state a)
        <*> "country" .: choiceWith countries (fmap country a)
        <*> "zipcode" .: string (fmap zipcode a)

data Region = Region
    { code :: String
    , fullName :: String
    }

countryChoices' :: HasPostgres m => m [(Text, (String, Text))]
countryChoices' = do
    countries <- getCountries
    return $ abbrToChoice countries

abbrToChoice :: [Region] -> [(Text, (String, Text))]
abbrToChoice regions =
    map (\ a -> ((pack $ code a), (code a, (pack $ fullName a)))) regions

这是调用它的处理程序:

editAddressH :: ([(T.Text, Splice AppHandler)] -> AppHandler ()) -> Addr.Address -> Maybe Int64 -> AppHandler ()
editAddressH renderer a userId = do
    addresses <- Addr.list userId
    (view, result) <- runForm "form" $ Addr.addressForm' (Just a) addresses -- line 233
    case result of
        Just x -> do
            r <- Addr.edit x -- line 236
            case r of
                _ -> renderer [("success", showContents), ("dfForm", hideContents)]
        Nothing -> renderer $ ("success", hideContents) : ("addressList", addressScriptSplice addresses) : phoneSplices ++ digestiveSplices view

我得到的错误是这样的:

src/Site.hs:233:44:
    No instance for (HasPostgres
                       (digestive-functors-0.5.0.1:Text.Digestive.Form.Internal.FormTree
                          (Handler App App) v0 (Handler App App)))
      arising from a use of `Addr.addressForm''
    Possible fix:
      add an instance declaration for
      (HasPostgres
         (digestive-functors-0.5.0.1:Text.Digestive.Form.Internal.FormTree
            (Handler App App) v0 (Handler App App)))
    In the second argument of `($)', namely
      `Addr.addressForm' (Just a) addresses'
    In a stmt of a 'do' expression:
        (view, result) <- runForm "form"
                        $ Addr.addressForm' (Just a) addresses
    In the expression:
      do { addresses <- Addr.list userId;
           (view, result) <- runForm "form"
                           $ Addr.addressForm' (Just a) addresses;
           case result of {
             Just x -> do { ... }
             Nothing
               -> renderer
                $   ("success", hideContents)
                  :   ("addressList", addressScriptSplice addresses)
                    :   phoneSplices ++ digestiveSplices view } }
src/Site.hs:236:40:
    Couldn't match expected type `Addr.Address'
                with actual type `digestive-functors-0.5.0.1:Text.Digestive.Form.Internal.FormTree
                                    m0 Text m0 Addr.Address'
    Expected type: Addr.Address
      Actual type: Form Text m0 Addr.Address
    In the first argument of `Addr.edit', namely `x'
    In a stmt of a 'do' expression: r <- Addr.edit x

看起来您需要单子函数。 它可能看起来像这样:

addressForm :: Monad m => Maybe Address -> [Address] -> Form Text m Address
addressForm a addrs = monadic $ do
    stateChoices <- getStatesFromDB
    countryChoices <- getCountriesFromDB
    return $
      Address
          <$> "id" .: choiceWith (addrToChoice addrs) (fmap id a)
          <*> "name" .: string (fmap name a)
          <*> "street" .: string (fmap street a)
          <*> "city" .: string (fmap city a)
          <*> "state" .: choiceWith stateChoices (fmap state a)
          <*> "country" .: choiceWith countryChoices (fmap country a)
          <*> "zipcode" .: string (fmap zipcode a)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM