I have a form where a user can update its username. A username should be unique. I thought of using the standard validation as mentioned in the Yesod book: Forms, but I don't get my head around it... Relevant database definition:
Profile
username Text
user UserId
UniqueProfile user
UniqueUsername username
Without validation, the user will receive an error-page (because of the username-uniqueness constraint on db-level). I want it to be more friendly.
How can I solve this? I was thinking that the validation should count the rows with the filled in username and should differ from the logged in UserId (a user can update other items too and keep its username). But how do I get that result to be used in the Left
part of the validation?
Solution:
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
I think you're looking for the checkM
function, which will allow you to perform arbitrary actions during the validation of a field.