2014-10-26 61 views
1

在使用Play和Anorm創建基本應用程序的過程中,我在處理尚未保存到數據庫的實體時遇到了問題。該表格顯然沒有ID字段,因此我無法使用案例類apply方法創建映射。我結束了創建兩個類 - 一個是堅持實體和一個尚未持久化和代碼看起來像這樣案例類,持久性和播放形式

case class EphemeralUser(email: String) 

case class PersistentUser(id: Long, email: String) 

val userForm = Form(mapping("email" -> text))(EphemeralUser.apply)(EphemeralUser.unapply) 

def create(user: EphemeralUser): PersistentUser = { /* Save with Anorm */ } 

有沒有更優雅的方式來處理它使用單個case class User(id: Option[Long], email: String)?或者甚至更好的方式來刪除代碼重複,因爲我有點喜歡持久和短暫的用戶是不同類型的事實。

+0

這有什麼錯兩種不同類型的?他們是不同的。一個得救,一個不能。當你有一個帶ID的類型的實例時,你知道它被保存了。當你有一個保存類型的實例時,你知道它有一個ID。 – drstevens 2014-10-26 22:15:26

+0

@drstevens我更喜歡兩種類型的方法,因爲附加的類型安全性,但有很多樣板。有一個特徵,它定義了所有字段和常見行爲,以及兩個構造函數,用於各自的案例類。雖然目前我不需要編輯表格,但似乎會有一些重複。 – synapse 2014-10-26 22:47:57

回答

1

我不認爲有必要需要兩種類型。使idOption[Long]應該是足夠的。要測試某個模型是否已被持續存在,只需要您檢查user.id.isDefined

Form可以再使用ignored仍然採取applyunapply優勢:

case class User(id: Option[Long], email: String) 

val userForm = Form { 
    mapping(
     "id" -> ignored[Option[Long]](None), 
     "email" -> email 
    )(User.apply)(User.unapply) 
} 
+0

我認爲這是正確的做法,至少,這是我在工作中所做的;我的案例類傾向於將持久性ID定義爲'Option [Long]'類型。當然,這假設您的持久性ID需要在數據模型中的應用程序中傳遞。 – 2014-10-26 21:40:05

+0

我唯一不喜歡的地方就是訪問'Option [Long]'id稍微不方便,但我願意忍受這種情況。 – 2014-10-27 01:19:21