【问题标题】:Yesod Persistent using Aeson to parse UTCTime into recordYesod Persistent 使用 Aeson 将 UTCTime 解析为记录
【发布时间】:2020-04-18 09:48:11
【问题描述】:

我的模型来自models.persistentmodels

...

Thing
    title Text
    price Int 
    kosher Bool
    optionalstuff [Text] Maybe
    createdat UTCTime
    updatedat UTCTime
    deriving Show

...

它包含两个时间字段,它们是UTCTime

我正在通过 AJAX 接收 几乎 Thing 的 JSON 格式。但是用户 JSON 不应该有 createdatupdatedatkosher。所以我们需要填写它们。

postNewEventR = do
    inputjson <- requireCheckJsonBody :: Handler Value
...
    -- get rawstringofthings from inputjson
...

    let objectsMissingSomeFields = case (decode (BL.fromStrict $ TE.encodeUtf8 rawstringofthings) :: Maybe [Object]) of
                        Nothing -> error "Failed to get a list of raw objects."
                        Just x  -> x

    now <- liftIO getCurrentTime

    -- Solution needs to go here:
    let objectsWithAllFields = objectsMissingSomeFields

    -- We hope to be done
    let things = case (eitherDecode $ encode objectsWithAllFields) :: Either String [Thing] of
                        Left err -> error $ "Failed to get things because: " <> err
                        Right xs  -> xs

这里出现错误“无法获取东西”是因为我们解析的 JSON 对象缺少模型中需要的字段。

【问题讨论】:

    标签: yesod aeson


    【解决方案1】:

    解决方案

    let objectsWithAllFields = Import.map (tackOnNeccessaryThingFields now True) objectsMissingSomeFields
    

    所以我们获取当前对象并添加缺失的字段,例如koshercreatedat

    但是 UTCTime 是 readaeson's way to parse UTCTime 的方式有一些奇怪的区别。因此,当我将 UTCTime 打印到 Aeson String 时,我需要将 UTCTime 打印成稍后期望的格式:

    tackOnNeccessaryThingFields :: UTCTime -> Bool -> Object -> Object
    tackOnNeccessaryThingFields t b hm = G.fromList $ (G.toList hm) <> [
                                                                                  ("createdat", String (pack $ formatTime defaultTimeLocale "%FT%T%QZ" t)),
                                                                                  ("updatedat", String (pack $ formatTime defaultTimeLocale "%FT%T%QZ" t)),
                                                                                  ("kosher", Bool b)
                                                                     ]
    
    tackOnNeccessaryThingFields _ _ _ = error "This isn't an object."
    

    在此修复之后,对象具有创建记录所需的所有字段,因此代码给出了[Thing]。 而且代码运行时没有运行时错误,而不是将tshow t解析为UTCTime。

    注意: 这个关于这个问题的 aeson github issue 似乎已关闭,但似乎不再允许:https://github.com/bos/aeson/issues/197

    感谢 Artyom: https://artyom.me/aeson#records-and-json-generics

    感谢普布里斯宾: https://pbrisbin.com/posts/writing_json_apis_with_yesod/

    感谢斯诺曼: 对于一切

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多