2016-02-05 66 views
2

我刚刚从Persistent from Yesod开始,已经打到我的第一个路障。如何忽略将由数据库填充的字段

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| 
User 
    email String 
    createdAt UTCTime Maybe default=CURRENT_TIME 
    updatedAt UTCTime Maybe default=CURRENT_TIME 
    deriving Show 
|] 

u <- insert $ User "[email protected]" Nothing Nothing 

我来自Rails背景,就像他们所倡导的架构设计惯例。在这种特殊情况下,每个表都有一个created_atupdated_at时间戳。但是,是否有任何方法可以不为每个将要创建的对象指定createdAtupdatedAt字段?

+1

不是我所知道的。但是你总是可以定义一个帮助函数,它需要一个电子邮件地址并返回一个填充了时间字段的'IO User'(你需要'IO'来获取当前时间)。另一种解决方案:写一个触发器。 – hao

回答

1

我对持久性知之甚少,但这种事情的常用技巧是定义一些参数化类型。例如,你可以写

data Dated a = Dated 
    { created :: UTCTime 
    , updated :: UTCTime 
    , value :: a 
    } 

那么你的裸值不需要担心自己的元数据和元数据可以均匀地所有不同类型的处理。例如你可能会暴露的API是这样的:

new :: a -> IO (Dated a) 
new a = do 
    now <- getUTCTime 
    return (Dated now now a) 

update :: Dated a -> a -> IO (Dated a) 
update old new = do 
    now <- getUTCTime 
    return (old { updated = now, value = new }) 

,那么我建议用newupdate导出Dated类型构造和它的所有领域,在一起,但没有导出Dated数据构造。这将确保createdupdated字段保持正确。