我的数据库中的每个表都需要created_at
和updated_at
字段用于一般卫生和家务管理。这导致Persistent模型看起来像这样:
User
email String Maybe
name String Maybe
tgramUserId TgramUserId Maybe
createdAt UTCTime
updatedAt UTCTime
deriving Show
现在,我有一堆用于根据不同的业务案例创建用户的API。例如:
我希望每个API的类型签名都是:
createUserFromX :: User -> SqlPersistM (Entity User)
但是,这意味着createUserFromX
的每个呼叫网站都需要拨打getCurrentTime
并设置createdAt
和updatedAt
内务管理字段。在这些API本身中本地化这种复杂性的方法是什么?
一个不洁净的(IMO)解决方案是将签名更改为:
createUserFromTelegram :: Maybe TgramUserId -> SqlPersistM (Entity User)
...但是这首先打破了使用记录类型的目的(在这个特定的例子中,你可能会赞成这种方法,但如果记录类型有10个字段会怎么样?)< / p>
答案 0 :(得分:3)
但是,这意味着createUserFromX的每个调用站点都需要调用getCurrentTime并设置createdAt和updatedAt管家字段。
事实并非如此。 SqlPersistM
的定义是:
type SqlPersistM = SqlPersistT (NoLoggingT (ResourceT IO))
type SqlPersistT = ReaderT SqlBackend
因此SqlPersistM
有一个MonadIO实例,您可以createUserFromX
在liftIO your_io_action
内执行任何IO操作:
createUserFromX :: User -> SqlPersistM (Entity User)
createUserFromX user = do
utctime <- liftIO getCurrentTime
let user' = user { createdAt = utctime, updatedAt = utctime }
-- your codes