CRUD: 管理機能ジェネレータ
CRUD (Create, Read, Update, Delete) モジュールは、JPA モデルオブジェクト用の完全に利用可能な web インタフェースを生成します。
CRUD モジュールの使い方
CRUD モジュールを使ってデータを管理するシンプルな例を見てみましょう。
アプリケーションで CRUD モジュールを利用可能にする
/conf/dependencies.yml
ファイルの require:
の後に次の行を追加することで、CRUD モジュールを有効にします:
require:
- play -> crud
新しいモジュールの依存性を取り込むために、ここで play dependencies
コマンドを実行します。
デフォルトの CRUD ルートの取り込み
conf/routes
ファイルに次の行を追加することで、モジュールのデフォルトのルートを取り込みます:
# Import CRUD routes
* /admin module:crud
この設定は、このあとに追加することになるいくつかのルートを、それぞれの CRUD コントローラに追加します。
デフォルトのルートファイルの使用は必須ではないことに 注意 してください。独自のルートを定義することも、これら 2 つを混ぜ合わせることも可能です。
User クラスの作成
CRUD モジュールはアプリケーションのモデルクラスにユーザインタフェースを提供します。 JPA エンティティである User モデルクラスの作成から始めましょう。
package models;
import play.*;
import play.db.jpa.*;
import javax.persistence.*;
import java.util.*;
@Entity
public class User extends Model {
public String name;
public String email;
public String address;
}
Users コントローラの作成
次に、CRUD コントローラを継承するだけのシンプルなコントローラを作成します。これは CRUD モジュールがルートを生成するために使用するある種の ‘マーカー’ です。
package controllers;
public class Users extends CRUD {
}
ここで http://localhost:9000/admin を開くと、User 管理画面が見えるはずです。
コントローラクラスの名前は、モデルクラス名の最後に ‘s’ を付けたものでなければなりません。違う名前を付けたい場合は、アノテーションを使うことができます。
package controllers;
import models.User;
@CRUD.For(User.class)
public class AdminUsers extends CRUD {
}
User フォーム
Add ボタンをクリックすると、User フォームが表示されるはずです。
User クラスにいくつかバリデーションルールを追加することができます:
package models;
import play.*;
import play.db.jpa.*;
import javax.persistence.*;
import java.util.*;
import play.data.validation.*;
@Entity
public class User extends Model {
@Required
@MinSize(8)
public String name;
@Required
@Email
public String email;
@Required
@MaxSize(1000)
public String address;
public String toString() {
return email;
}
}
User フォームを更新すれば、バリデーションが自動的に適用されていることを確認できるでしょう。
フォームラベルの変更
アプリケーションの conf/messages
ファイルに以下の行を追加してください:
name=Name
email=Email address
address=Postal address
そして、User フォームを更新してください:
User の作成とリストビューのカスタマイズ
デフォルトのリストビューは、オブジェクトの toString()
メソッドの結果を含むただひとつの列を使用します。
このビューをカスタマイズするには、アプリケーションに /app/views/Users/list.html
テンプレートを作成する必要があります。
シェルを開いてアプリケーションディレクトリに移動したら、以下をタイプします:
play crud:ov --template Users/list
このコマンドは、CRUD のデフォルトの list.html
テンプレートを、アプリケーションの Users/list.html
にコピーしますが、もしこのファイルが存在すれば上書きします。
このテンプレートを以下のように編集してください:
#{extends 'CRUD/layout.html' /}
<div id="crudList" class="${type.name}">
<h2 id="crudListTitle">&{'crud.list.title', type.name}</h2>
<div id="crudListSearch">
#{crud.search /}
</div>
<div id="crudListTable">
#{crud.table fields:['email', 'name'] /}
</div>
<div id="crudListPagination">
#{crud.pagination /}
</div>
<p id="crudListAdd">
<a href="@{blank()}">&{'crud.add', type.modelName}</a>
</p>
</div>
そして、リストを更新してください。
フィールドレンダリングのカスタマイズ: crud.custom タグ
それぞれの User
エンティティの、リストやフォームビューにおける表示のされ方をカスタマイズすることで、ちょっと前進することができます。
フィールドをカスタマイズするには、 #{crud.custom}
タグを使用します:
#{crud.table fields:['name', 'company']}
#{crud.custom 'company'}
<a href="@{Companies.show(object.company.id)}">
${object.company.name}
</a>
#{/crud.custom}
#{/crud.table}
カスタムハンドラを定義することで、追加の列や入力フォームを表示することもできます:
#{crud.table fields:['name', 'company', 'edit']}
#{crud.custom 'company'}
<a href="@{Companies.show(object.company.id)}">${object.company.name}</a>
#{/crud.custom}
#{crud.custom 'edit'}
<a href="@{Users.edit(object.id)}">Edit</a>
#{/crud.custom}
#{/crud.table}
文字列のリストと列挙型のリスト
CRUD モジュールはフィールドを文字として表示します。この文字フィールドにおいて、リストはカンマで区切られた文字列として表示されます。例えば:
@Entity
public class Account extends Model {
@CollectionOfElements
public Set<ContentType> contentTypes;
@CollectionOfElements
public Set<String> usernames;
public Account(Set<String> usernames) {
super();
this.usernames = usernames;
}
}
これは、次のように表示されます: contentTypes は “myEnumId1”,“myEnumId2” と表示され、usernames は “string1”,“string2” と表示されます。それぞれの定義において、これが CRUD モジュールで行うべき最初のカスタマイズです。
show と blank ビューの一般的なカスタマイズ方法
CRUD ビューの振る舞いに主に影響するのは、それぞれの列の ObjectType
です。このため、
例えば @Version
アノテーションの付いたフィールドを隠すと言ったように、 CRUD モジュールの振る舞いを一般的な方法で変更したい場合、独自の ObjectType
クラスを作成することができます。コントローラまたはコントローラのスーパークラスに static メソッドを宣言しなければなりません。
protected static ObjectType createObjectType(Class<? extends Model> type) {
return new VersionObjectType(type);
}
以下に完全な例を示します:
public class CustomAdminCompany extends CRUD {
protected static ObjectType createObjectType(Class<? extends Model> type) {
return new VersionObjectType(type);
}
public static class VersionObjectType extends ObjectType {
private final String versionColumn;
public VersionObjectType(Class<? extends Model> modelClass) {
super(modelClass);
versionColumn = getVersionColumnName(modelClass);
}
private String getVersionColumnName(Class modelClass) {
Class c = modelClass;
try {
while (!c.equals(Object.class)) {
for (Field field : c.getDeclaredFields()) {
if (field.isAnnotationPresent(Version.class)) {
return field.getName();
}
}
c = c.getSuperclass();
}
} catch (Exception e) {
throw new UnexpectedException("Error while determining the "
+ "object @Version for an object of type " + modelClass);
}
return null;
}
@Override
public List<ObjectField> getFields() {
List<ObjectField> result = super.getFields();
for (ObjectField objectField : result) {
if (objectField.name.equals(versionColumn)) {
objectField.type = "hidden";
}
}
return result;
}
}
}
これで終わりではありません; findPage
やその他のメソッドをカスタマイズすることもできます。ソースコードを覗いてみてください。
ローカライズ
CRUD モジュールのメッセージをアプリケーションの conf/messages
ファイルで上書きすることで、ユーザインタフェースをローカライズすることができます。
crud.add=Create new &{%s}
CRUD モジュール自身のメッセージファイル: $PLAY_HOME/modules/crud/conf/messages
を見て、どのメッセージキーが使用されているか確認してください。
コマンド
CRUD モジュールは、コマンドラインから使って、デフォルトのテンプレートを上書きする crud:override コマンドを提供します。これが機能するのは、CRUD モジュールはアプリケーションのテンプレートが存在する場合に、自身のテンプレートではなく、アプリケーションのものをロードするためです。 crud:override
の代わりに crud:ov
を使用することもできます。
play crud:override --template [path]
例えば Users/list
のようにパスで指定したテンプレートを、アプリケーションの app/views/CRUD
ディレクトリにコピーします。 --template
の代わりに -t
を使用することもできます。
play crud:override --layout
メインのレイアウトテンプレートである layout.html
を上書きします。
play crud:override --css
スタイルシート crud.css
を public/stylesheets/
ディレクトリにコピーして上書きします。
制限事項
CRUD モジュールは、双方向の関連を持つふたつのエンティティのうち、ひとつのみ: mappedBy
属性を持たないエンティティを表示します。