我有我的模特models.persistentmodels
...
Thing
title Text
price Int
kosher Bool
optionalstuff [Text] Maybe
createdat UTCTime
updatedat UTCTime
deriving Show
...
它包含两个时间字段,它们是UTCTime
。
我通过AJAX收到JSON中的[[几乎 a Thing
]。但是用户JSON不应具有createdat
和updatedat
或kosher
。因此,我们需要填写它们。
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对象缺少模型中所需的字段。
read
与aeson'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。注意:这个关于这个问题的eson github问题似乎已关闭,但似乎不再允许:https://github.com/bos/aeson/issues/197
感谢Artyom:https://artyom.me/aeson#records-and-json-generics
感谢Pbrisbin:https://pbrisbin.com/posts/writing_json_apis_with_yesod/感谢Snoyman:对于一切