grailsアプリケーションでコマンドオブジェクトを使用する際に好ましいパターンがあるのではないかと思います。特に、オブジェクトを保存するための別のメソッドを定義する必要がある場合、またはフォームの表示と保存に同じコントローラーメソッドを使用する必要がある場合はどうなりますか?
フォームを表示してオブジェクトを保存するための別々のメソッドの例を示しましょう
def user(int id) {} // shows the edit user form - user.gsp. Submit takes us to saveUser method
def saveUser(UserCommand cmd) {} // actually saves the user, then redirects somewehre else
すべてが機能するはずですが:
検証エラーが発生した場合、saveUser
メソッドはメソッドが実行したロジック全体を実行する必要がありuser
ます。ユーザーフォームを表示する前に、データベースから追加のオブジェクトをロードしたり、計算を実行したりする必要がある場合は、フォームを再度表示して検証エラーを含める必要があるため、もう一度実行する必要があります。これは不必要なコードの重複につながります。user
コマンドオブジェクトとそれに関連するエラーが失われるため、検証が失敗したときにメソッドにリダイレクトできません。したがって、検証エラーを表示できません。
フォームの保存と表示に同じ方法を使用した別の例
def user(UserCommand cmd, Integer id) {
def u=User.load(id)
if (request.method=="POST"&&cmd.validate()) {
// populate u with command object values and save in database
// then redirect somewhere
}
}
この例では、コードを複製する必要がありません。ユーザーの保存は、POST
リクエストがあった場合にのみ実行されます。それ以外の場合は、フォームのみが表示されます。検証エラーの場合、それらはアクセス可能であり、gspページに表示できます。
主な問題はGET
、ユーザーページへのリクエストがある場合(つまり、user.gspフォームが表示されている場合でも)、空のコマンドオブジェクトインスタンスが作成および検証されることです(同じコントローラーで定義されているため)。したがって、フォームが表示されるたびに、提供された値が空であるという検証エラーが発生します(コマンドオブジェクトが空であるため)
どちらのシナリオも正しく機能するように簡単に変更できます(たとえば、シナリオ1のセッションでリダイレクトする前にコマンドオブジェクトを保存しPOST
、シナリオ2でリクエストがあった場合にのみ検証エラーを表示します)が、追加のコードが必要で、あまり洗練されていないようです。
この問題に対するより単純な、より多くの「grails」ソリューションはありますか?