如何处理记录类型中的“管家”字段?

时间:2016-03-06 11:20:37

标签: haskell yesod persistent

我的数据库中的每个表都需要created_atupdated_at字段用于一般卫生和家务管理。这导致Persistent模型看起来像这样:

User
  email String Maybe
  name String Maybe
  tgramUserId TgramUserId Maybe
  createdAt UTCTime
  updatedAt UTCTime
  deriving Show

现在,我有一堆用于根据不同的业务案例创建用户的API。例如:

  • createUserFromWebForm
  • createUserFromTelegram
  • createUserFromOAuth

我希望每个API的类型签名都是:

createUserFromX :: User -> SqlPersistM (Entity User)

但是,这意味着createUserFromX的每个呼叫网站都需要拨打getCurrentTime并设置createdAtupdatedAt内务管理字段。在这些API本身中本地化这种复杂性的方法是什么?

一个不洁净的(IMO)解决方案是将签名更改为:

createUserFromTelegram :: Maybe TgramUserId -> SqlPersistM (Entity User)

...但是这首先打破了使用记录类型的目的(在这个特定的例子中,你可能会赞成这种方法,但如果记录类型有10个字段会怎么样?)< / p>

1 个答案:

答案 0 :(得分:3)

  

但是,这意味着createUserFromX的每个调用站点都需要调用getCurrentTime并设置createdAt和updatedAt管家字段。

事实并非如此。 SqlPersistM的定义是:

type SqlPersistM = SqlPersistT (NoLoggingT (ResourceT IO))
type SqlPersistT = ReaderT SqlBackend

因此SqlPersistM有一个MonadIO实例,您可以createUserFromXliftIO your_io_action内执行任何IO操作:

createUserFromX :: User -> SqlPersistM (Entity User)
createUserFromX user = do
    utctime <- liftIO getCurrentTime
    let user' = user { createdAt = utctime, updatedAt = utctime }
    -- your codes