基于数据库中的值进行表单验证

时间:2012-12-09 20:21:26

标签: haskell validation yesod

我有一个表单,用户可以在其中更新其用户名。用户名应该是唯一的。我想过使用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

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找checkM函数,它允许您在字段验证期间执行任意操作。