Slim3 で Text 型で保存したい文字列を取り扱う場合
先日、
というエントリを書いたが、親切に現在の Slim3 で Text 型を扱う場合の方法を教えてもらうことができた。
Slim3 で Text 型を扱う際に何が問題だったのか
Text 型で保存した文字列を View 側で表示させる際に、Slim3の JSP Function で Text 型から String 型に変換して全文を表示させられないことだった。
実際にやろうとしていたことは、Text 型で保存したと仮定する値 body を View で表示させようとした場合、通常の h でそのまま表示させようとすると、
${f:h(e.body)}
Text#toString() では、Text 型で保存した文字列の「基になる文字列の最初の 70 文字を返します」という処理になり、文字列すべてが表示されるわけではない。
そのため、文字列すべてを表示させるために、Text 型で保存した値 body を String 型に変換して表示させる必要がある。そのメソッドは Text#getValue() を利用する必要がある。しかし、
${f:h(e.body.getValue())}
と書くと実行時にエラーが発生して、正常に動作しない。
そのため、Controller か ModelService か、それとも Model 内で Text 型の値を一度 String 型に変換して、エラーを回避する方法しかないと考えたのだ。
実際の対応方法
Model クラス側で Text 型で保存したいと考えている値に対して、「@Attribute(lob = true)」を宣言するだけである。
例えば、上記の値 body の場合は、Model クラス内で
private Text body;
と記述していた箇所を
@Attribute(lob = true) private String body;
と変更するだけでいい。
なぜこれだけの変更でいいのか
Text 型の宣言を、String 型の宣言 + 「@Attribute(lob = true)」に変更するだけで、ModelMeta クラス内で型変換をしてくれる実装を自動で記述してくれるからだ。
実際に変更された箇所としては、変更前は、
(前略) public final org.slim3.datastore.UnindexedAttributeMeta<news.model.Article, com.google.appengine.api.datastore.Text> body = new org.slim3.datastore.UnindexedAttributeMeta<news.model.Article, com.google.appengine.api.datastore.Text>(this, "body", "body", com.google.appengine.api.datastore.body.class); (中略) model.setbody((com.google.appengine.api.datastore.Text) entity.getProperty("body")); (中略) entity.setUnindexedProperty("body", m.getBody()); (後略)
となっていたのが、
(前略) public final org.slim3.datastore.StringUnindexedAttributeMeta<news.model.Article> body = new org.slim3.datastore.StringUnindexedAttributeMeta<news.model.Article>(this, "body", "body"); (中略) model.setBody(textToString((com.google.appengine.api.datastore.Text) entity.getProperty("body"))); (中略) entity.setUnindexedProperty("body", stringToText(m.getBody())); (後略)
と内部処理が変更されている。