我有一个表单,用户可以在其中更新其用户名。用户名应该是唯一的。我想过使用Yesod书中提到的标准验证:Forms,但我不理解它...相关的数据库定义:
Profile
username Text
user UserId
UniqueProfile user
UniqueUsername username
如果没有验证,用户将收到错误页面(因为db-level上的用户名唯一性约束)。我希望它更友好。
我该如何解决这个问题?我认为验证应该使用填写的用户名来计算行数,并且应该与登录的UserId不同(用户也可以更新其他项目并保留其用户名)。但是,如何在验证的Left
部分中使用该结果?
解决方案:
profileForm :: Maybe ProfileForm -> Form ProfileForm
profileForm mpf = renderBootstrap $ ProfileForm
<$> areq usernameField (FieldSettings {fsLabel = "Username", fsTooltip = Nothing, fsId = Nothing, fsName = Nothing, fsAttrs = [("autofocus","autofocus")]}) (pfUsername <$> mpf)
where
unav x = do
(Entity uid _) <- requireAuth
usernamecount <- runDB $ count [ ProfileUsername ==. x
, ProfileUser !=. uid ]
return $ if usernamecount > 0
then Left ("Username already taken" :: Text)
else Right x
usernameField = checkM unav textField