2016-02-05 64 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字段保持正確。