У меня есть вызов ajax, отправляющий json на маршрут в Yesod, и я хочу, чтобы маршрут анализировал json и вставлял его непосредственно в базу данных. В моем файле модели у меня есть
createtime UTCTime default=now()
что препятствует синтаксическому анализу json, поскольку клиент не отправляет время создания. Я попытался написать свой собственный parseJson для записей журнала, но мне не удалось вставить UTCTime по умолчанию, так как getCurrentTime возвращает значение в монаде IO. Я бы хотел, чтобы база данных установила значение, если это возможно.
Единственное, что я могу придумать на данный момент, это создать тип, подобный LogEntryWithoutTime, проанализировать JSON и преобразовать его в LogEntry. Есть ли более простой способ?
Изменить: я показываю три разных сбоя при добавлении getCurrentTime к синтаксическому анализу JSON. Во-первых, цель состоит в том, чтобы проанализировать время создания, если оно доступно, и по умолчанию использовать getCurrentTime на сервере. В любом случае это неправильно, так как мы не должны полагаться на время клиента.
instance FromJSON Log where
parseJSON (Object o) = Log
<$> o .: "userid"
...
<*> o .:? "createtime" .!= liftIO getCurrentTime
Ошибка
Model.hs:58:32:
Couldn't match expected type ‘UTCTime’
with actual type ‘m0 UTCTime’
In the second argument of ‘(.!=)’, namely ‘liftIO getCurrentTime’
In the second argument of ‘(<*>)’, namely
‘o .:? "createtime" .!= liftIO getCurrentTime’
Во-вторых, я пытаюсь просто получить текущее время.
<*> liftIO getCurrentTime
и я получаю ошибку
Model.hs:58:9:
No instance for (MonadIO
aeson-0.7.0.6:Data.Aeson.Types.Internal.Parser)
arising from a use of ‘liftIO’
In the second argument of ‘(<*>)’, namely ‘liftIO getCurrentTime’
Если я изменю строку на
<*> getCurrentTime
тогда я получаю
Model.hs:58:9:
Couldn't match type ‘IO’
with ‘aeson-0.7.0.6:Data.Aeson.Types.Internal.Parser’
Expected type: aeson-0.7.0.6:Data.Aeson.Types.Internal.Parser
UTCTime
Actual type: IO UTCTime