0

Play2.0 について質問があります :-)。

というモデルがありTaskます。このタスクには、 というフィールドが含まれていますcreatedBy。このフィールドには、ログインしているユーザーを入力する必要があります。

私のフィールド宣言は次のようになります。

@ManyToOne
@Constraints.Required
public User createdBy;

ログインしたユーザーがドロップダウン ボックスから説明優先度を入力できるフォームをレンダリングします。フォームが送信されたら、メソッドを呼び出しますsave()。save メソッドには、次のコードがあります。

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

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

フィールドには(有効な)ユーザーが含まれていないため、明らかにTask保存されません。ユーザーへの唯一の参照は、セッションの主キーではなく、一意のコードcreatedByを保存することです。

必須の制約を削除し、保存されたタスクにユーザーをポストフィルした場合にのみ機能します。フォームとユーザーを結び付けるもっと良い方法があるはずですよね?

4

2 に答える 2

2

Play2.0 があなたに求めているのは、「データベース モデル」と「フォーム Bean」を区別することです。また、より良い解決策があるべきだと思います。しかし一方で、それはかなりきれいです。したがって、あなたがすべきことは次のとおりです。

  1. TaskFormたとえば、という「フォーム Bean」を作成します。このクラスには、フォームに表示されるフィールドのみが含まれ、適切な注釈と検証が行われます。
  2. を返すtoTask(User user)メソッドを作成します。TaskFormTask
  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 開発者のアイデアは、バインド/検証に Form クラスを使用することです。この Form クラスは、既存のクラスをラップします。このラップされたクラスがフォームの 1 対 1 の表現であるという彼らの考えには何の問題もないと思います。唯一の問題は、Scala 言語の方が Java 言語よりもはるかに簡単であることです。Java では多くの「フォーム表現クラス」を作成する必要がありますが、Scala では「マッピング」や「ケース クラス」などを使用できます ( ScalaForms を参照)。)。したがって、1 つの異なるプロパティに対して新しい「フォーム Bean」を作成するのはおそらく価値がなく、1 つの場所で検証を行いたいというコメントのポイントに完全に同意します。しかし、それはまだそれがどのように設計されているかです。自分で API を変更するか、他の誰かが 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

モデルから必要なアノテーションを削除し、次の2つの手順で新しいタスクをバインドします。

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 に答える