0

我又来这里问关于 Play2.0 的问题 :-)。

我有一个模型叫Task. 此任务包含一个名为 的字段createdBy。必须使用登录用户填充此字段。

我的字段声明如下所示:

@ManyToOne
@Constraints.Required
public User createdBy;

我呈现了一个表单,登录用户可以在其中从下拉框中输入描述优先级。提交表单后,我调用我的save()方法。在保存方法中,我有以下代码:

Form<Task> taskForm = form(Task.class).bindFromRequest();

if (taskForm.hasErrors()) {
    return badRequest(views.html.tasks.taskCreate.render(taskForm));
}
taskForm.get().save();

显然,Task永远不会保存,因为该字段createdBy不包含任何(有效)用户。对用户的唯一引用是我保存了他的唯一代码,而不是会话中的主键。

只有当我删除Required约束并将用户后填到保存的任务时,我才能让它工作。必须有更好的方法将表单和用户绑定在一起,对吧?

4

2 回答 2

2

Play2.0 希望您做的是区分您的“数据库模型”和“表单 bean”。我也认为应该有更好的解决方案。但另一方面,它非常干净。所以你应该做的是:

  1. 例如,创建一个名为 的“表单 bean” TaskForm。此类仅包含表单中显示的字段,以及正确的注释和验证。
  2. toTask(User user)在您的方法中创建一个TaskForm返回Task.
  3. 将控制器中的代码更改为:

    Form<TaskForm> taskForm = form(TaskForm.class).bindFromRequest();
    
    if (taskForm.hasErrors()) {
      return badRequest(views.html.tasks.taskCreate.render(taskForm));
    }
    taskForm.get().toTask(user).save();
    
  4. 将注释/验证保留在“模型类”Task中,但将它们视为数据库验证,而不是表单验证。

编辑:

  • 一些额外的解释:我在 Play 组中讨论了这个验证/绑定问题:讨论1 ,讨论2 。据我了解,Play Developers 的想法是使用 Form 类进行绑定/验证。这个 Form 类包装了一个现有的类。我认为他们认为这个包装的类是表单的一对一表示并没有错。唯一的问题是,Scala 语言比 Java 语言更容易做到这一点。在 Java 中,您必须创建许多“表单表示类”,而在 Scala 中,您可以使用“映射”和“案例类”之类的东西(参见 ScalaForms)。因此,我完全同意您在评论中的观点,即可能不值得为一个不同的属性编写一个新的“表单 bean”,您宁愿在一个地方进行验证。但这就是它的设计方式。我希望他们要么自己更改 API,要么其他人仔细查看并提交拉取请求。但是现在,这就是框架希望您进行绑定/验证的方式。

  • 例子:

    public class Task extends Model {
    
        @Constraints.Required
        public String description;
    
        @Constraints.Required
        public Integer priority;
    
        @ManyToOne
        @Constraints.Required
        public User createdBy;
    
        public Task() {
        }
    
        public Task(final TaskForm taskForm, final Long userCode) {
            description = taskForm.description;
            userCode = taskForm.userCode;
            createdBy = User.findByCode(userCode);
        }
    
    }
    
    public class TaskForm {
    
        @Constraints.Required
        public String description;
    
        @Constraints.Required
        public Integer priority;
    
        public toTask(final Long userCode) {
            return new Task(this, userCode);
        }
    
    }
    
    public class Tasks extends Controller {
    
        public static Result save() {
            Form<TaskForm> taskForm = form(TaskForm.class).bindFromRequest();
    
            if (taskForm.hasErrors()) {
                return badRequest(views.html.tasks.taskCreate.render(taskForm));
            }
            taskForm.get().toTask(session("userCode")).save();
        }
    
    }
    
于 2012-04-19T21:05:20.407 回答
0

从模型中删除所需的注释并分两步绑定新任务:

Form<Task> taskForm = form(Task.class).bindFromRequest();

if (taskForm.hasErrors()) {
    return badRequest(views.html.tasks.taskCreate.render(taskForm));
}

Task newTask = taskForm.get();
newTask.createdBy = someObjectOfUserModel;
newTask.save();

return ok("New user added");
于 2012-04-19T20:08:20.347 回答