我无法根据用户的角色验证和重置某些字段。 我正在尝试使用grails开发一个rest api,当我尝试根据用户的角色重置某些字段时出现问题。我发送了一个带有所需"不允许"通过PUT更改为控制器。我将不允许的字段修改为对我来说正确的字段然后调用.save()和"不允许字段#34;字段使用其发送的值更新,而不是使用由我修改的值更新。这是代码。
模特
package phonebook
class User {
String firstName
String lastName
String phoneNo
String address
String email
String password
boolean active = false
String hash
String authToken = ""
String role = "user"
static hasMany = [contacts:Contact]
static constraints = {
firstName(blank: false)
lastName(blank: false)
address(blank: true)
phoneNo(unique: true)
email(blank: false, unique: true)
password(blank: false)
role(blank: false, inList: ["user", "admin"])
hash(blank: true)
authToken(blank: true)
active(inList:[true,false])
}
}
控制器的方法:
@Transactional
def update(User userInstance) {
if (!isAuthenticated()){
notAllowed()
return
}
if (userInstance == null) {
notFound()
return
}
//if(isAdmin()){
def userBackup = User.findById(userInstance.id)
userInstance.role = userBackup.role
userInstance.active = userBackup.active
userInstance.hash = userBackup.hash
userInstance.authToken = userBackup.authToken
//}
if (userInstance.hasErrors()) {
respond userInstance.errors, view:'edit'
return
}
userInstance.save flush:false
request.withFormat {
'*'{ respond userInstance, [status: OK] }
}
}
JSON SENT VIA PUT
{
"id":"1",
"firstName": "Modified Name 23",
"role":"admin",
"active":"true",
"hash":"asdasd"
}
上述代码不应修改哈希值或活动或角色的值,即使它们已被发送。
有什么想法吗? 感谢。
答案 0 :(得分:3)
保存更改的原因是因为默认情况下,对域实例所做的任何更改都将在会话结束时刷新。这被称为具有自动会话刷新功能的开放会话。我建议你对人们在GORM面临的一些主要问题上做some reading。
正确使用discard可能会解决您的问题。退出控制器之前,请放弃实例更改。
例如:
if (!isAuthenticated()){
notAllowed()
userInstance.discard()
return
}
修改强>
根据评论中的对话,这可能是解决您问题的方法。丢弃和附加的组合。
userInstance.discard()
def userBackup = User.findById(userInstance.id)
userInstance.role = userBackup.role
userInstance.active = userBackup.active
userInstance.hash = userBackup.hash
userInstance.authToken = userBackup.authToken
userInstance.attach()
答案 1 :(得分:0)
我得到了这种方法的帮助。
实施例
def update(ShopItem shopItemInstance) {
if (shopItemInstance == null) {
notFound()
return
}
if (!shopItemInstance.itemPhoto){
shopItemInstance.itemPhoto =
shopItemInstance.getPersistentValue("itemPhoto");
}
if (shopItemInstance.hasErrors()) {
respond shopItemInstance.errors, view:'edit'
return
}
shopItemInstance.save flush:true
redirect(action: "show", id: shopItemInstance.id)
}
在你的情况下:
userInstance.role = userInstance.getPersistentValue("role")
userInstance.active = userInstance.getPersistentValue("active")
userInstance.hash = userInstance.getPersistentValue("hash")
userInstance.authToken = userInstance.getPersistentValue("authToken")
答案 2 :(得分:0)
如果您将使用命令对象功能,那就更好了。您可以将命令对象与请求有效负载绑定,对其进行验证,然后查找并更新域对象。
您可以在此处找到更多详细信息: http://grails.org/doc/2.3.x/guide/theWebLayer.html#commandObjects
根据记录,你不应该在你的控制器中使用@Transactional。您可以将该代码移动到服务中。
等式:
def update(Long id,UserCommand cmd){ // Grails会将json对象映射到命令对象中,如果使用@Validatable注释类,将调用validate()方法
}