Search code examples
grails

in grails 3, with command objects, how do you NOT update say password field?


If you have a service method save(User user) which simply calls user.save(), how do you stop it overwriting the password with a blank value (or failing validate if its null) if the user had say edited his address? the password is not sent to the update view. In the old days, we used to have something like this:

def update(Map params) {
    params.remove("password")
    player.properties = params
    player.save()
}

Now we have this:

   interface IUserService {
      User get(Serializable id)
      List<User> list(Map args)
      Long count()
      void delete(Serializable id)
      User save(User user)
      User update(User user)
   }

@Service(User)
@Transactional
abstract class UserService implements IUserService {
    @Override
    User update(User user) {
        user.save() // this will overwrite the password, or fail if the password is null.
}

What is the new equivalent of params.remove? How do we not update the password on updating of the object? I guess we could read the current password out of the DB, and assign it to the passed in object before saving, but this is another read. Or we could write some custom sql which updates each field but not the ones we want to mask?


Solution

  • You can configure properties to not participate in mass property binding using the bindable constraint.

    class User {
        String username
        String password
    
        static constraints = {
            password bindable: false
        }
    }
    

    Now the data binder will exclude the password property during the data binding process and you get to decide when/if that property is updated. You could do something like per.password = params.password (or similar) whenever you want to update the password.