2
2

More than 5 years have passed since last update.

[Grails]ドメイン名と異なるコントローラでscaffolding

Last updated at Posted at 2014-08-22

概要

例えばHogeというドメインがある場合、普通であればHogeControllerというコントローラを用意して、それをHogeドメインのscaffolding用コントローラにします。
ところが、ドメイン名とscaffold用のコントローラ名を別のものにしたい!という要望がよく出てきます(自分の場合)

そういう場合、別名のコントローラのプロパティに、このコントローラはHogeドメインのscaffoldようだよという宣言をしてあげることで対応できます。
例えばTestControllerというコントローラでHogeドメインを扱いたい場合は以下のようにします。

TestController.groovy
class TestController {
    static scaffold = Hoge
}

コレだけでOK!!
/test/にアクセスすれば、ちゃんとHogeドメインの一覧が表示されます。

問題点

じつはこの状態だと、データの閲覧はできますが新規登録、更新、削除ができません。
というのも、フォームの送信先のコントローラ名が、ドメイン名になってしまうためです。

解決方法

コレを回避するために、テンプレートを修正します。

テンプレートのインストール

まずは以下のコマンドを実行してテンプレートを編集できるようにします。

grails install-templates

create.gspの修正

formタグの修正

src/templates/scaffolding/create.gspのformタグを以下のように編集します。

修正前

<g:form url="[resource:${propertyName}, action:'save']" <%= multiPart ? ' enctype="multipart/form-data"' : '' %>>

修正後

<g:form url="[action:'save']" method="POST" <%= multiPart ? ' enctype="multipart/form-data"' : '' %>>

edit.gspの修正

フォームタグの修正

src/templates/scaffolding/edit.gspのformタグを以下のように修正します。

修正前

<g:form url="[resource:${propertyName}, action:'update']" method="PUT" <%= multiPart ? ' enctype="multipart/form-data"' : '' %>>

修正後

<g:form url="[action:'update']" method="PUT" <%= multiPart ? ' enctype="multipart/form-data"' : '' %>>

hiddenフィールドの追加

さらにhiddenFieldをg:actionSubmitタグの上に追記します。

src/templates/scaffolding/edit.gsp
<!--g:hiddenFieldを追記-->
<g:hiddenField name="id" value="\${${propertyName}?.id}" />
<g:actionSubmit class="save" action="update" value="\${message(code: 'default.button.update.label', default: 'Update')}" />

show.gspの修正

次に、src/templates/scaffolding/show.gspのフォームタグの部分を以下のように修正します。

修正前

src/templates/scaffolding/show.gsp
<g:form url="[resource:${propertyName}, action:'delete']" method="DELETE">
<fieldset class="buttons">
  <g:link class="edit" action="edit" resource="\${${propertyName}}">
    <g:message code="default.button.edit.label" default="Edit" />
  </g:link>
  <g:actionSubmit class="delete" action="delete" value="\${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('\${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" />
</fieldset>
</g:form> 

修正後

src/templates/scaffolding/show.gsp
<g:form url="[action:'delete']" method="DELETE">
<fieldset class="buttons">
  <g:link class="edit" action="edit" params="[id:${propertyName}.id]">
    <g:message code="default.button.edit.label" default="Edit" />
  </g:link>
  <g:hiddenField name="id" value="\${${propertyName}?.id}" />
  <g:actionSubmit class="delete" action="delete" value="\${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('\${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" />
</fieldset>
</g:form>

resource="\${${propertyName}}を削除します。
さらに、linkタグのパラメータの修正と、edit.gsp同様にhiddenFieldを追記しています。
コレでひとまず動作します。

Controller.groovyの修正

処理自体はテンプレート通りで特に問題ありませんが、データベースを更新したあとのリダイレクトの宛先のコントローラ名が、ドメイン名になってしまっているので、その部分を修正します。
該当ファイルは、テンプレートである/src/templates/scaffolding/Controller.groovyです。
saveメソッドとupdateメソッド両方で同じように修正する必要があります。
修正前

src/templates/scaffolding/Controller.groovy
request.withFormat {
    form multipartForm {
        flash.message = message(code: 'default.updated.message', args: [message(code: '${className}.label', default: '${className}'), ${propertyName}.id])
        redirect ${propertyName}
    }
    '*'{ respond ${propertyName}, [status: OK] }
}

修正後

src/templates/scaffolding/Controller.groovy
request.withFormat {
    form multipartForm {
        flash.message = message(code: 'default.created.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), ${propertyName}.id])
        redirect action: 'show', id:${propertyName}.id
    }
    '*' { respond ${propertyName}, [status: CREATED] }
}

redirectの部分を修正しています。
コレで、モデルの更新後のリダイレクトが正常に動作するようになります。

まとめ

やることといえば、基本的にはテンプレートをちょこっと修正するだけです。
テンプレートを元に戻したい場合はVCSから戻すのもいいし、サイトinstall-templateを実行してもOKです。
また、やっぱりドメイン名と同名のコントローラでscaffoldしたい!となった場合、今回の修正をしていても問題なくscaffoldは動作します。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2