アーカイブ

playでブログを作る(タグ編)

トレーニングでplay frameworkでブログを作ってた。

タグをつけるところで若干詰まったのでメモ。

 

まずModelでBlogとTagをManyToManyで連携。

そしてBlogとTagを合わせた入力フォーム用のクラスを用意。


public class Entry {

public String title;
public String content;
public String tag;

}

それをformヘルパーで表示してcontrollerでpostされたのをbindfromrequestしてget()する。
ここでgetした内容をそれぞれに分けてsave()
Tagはカンマで区切ったものを分割してそれぞれ登録。

 


/*Blogのデータを保存*/
Blog blogData = new Blog();
blogData.title = f.get().title;
blogData.content = f.get().content;
blogData.save();

 

String input = f.get().tag.replaceAll("\\u0020",""); //空白を削除
String[] arr = input.split(","); //入力されたTagを分割して配列にする。

for(String tag : arr){
Tag t = Tag.find.where().eq("name",tag).findUnique(); //配列からひとつ取り出して既存のタグかどうか検索。

if(t == null){ //タグが存在してないなら…

Tag tagData = new Tag();
tagData.name = tag;
tagData.blog.add(blogData); //blogの記事と紐付ける。blog.tagはリストなのでadd()で追加。
tagData.save();

 

blogData.tag.add(tagData); //blog側をタグと紐付けて更新。
blogData.update();

}else{ //タグが存在するなら…

t.blog.add(blogData); //blogの記事と紐付けて更新。
t.update();

 

blogData.tag.add(t); //blog側をタグと紐付けて更新。
blogData.update();

}

}

気になったのはManyToManyに(cascade = CascadeType.ALL)を設定しておけば片方だけ紐付ければもう片方も自動で紐付けてくれるのでは…?ということ。
残念ながらしてくれなかったので両方とも紐付ける必要があった。

ManyToManyはお互いに相手を配列として紐付けるので、
blog.tag には Tag が、tag.blog にはBlogタイプが入るのでadd()で追加しないといけない…たぶん。

ちなみに更新の際は一度タグとブログの関連づけをリセットした上でもう一度タグを入力した方が良さそう。
カスケードが動かないのはなぜだろう…謎。

広告

herokuへplayをデプロイ

試しにPlayをherokuへアップしたのでメモ。

やり方はググればすぐに出てくると思うので省略。

 

$git push git@heroku.com:アプリ名 master

 

これで特にエラーがなければデプロイ完了。

しかし…なぜかplay version 1.2.7で起動されるというエラーが発生。

どうやらgitのレポジトリとPlayプロジェクトが一致してないとそうなるらしい?

とりあえずgitを初期化してやり直したら成功。

 

その後、play runしたところ動くけれど動作がどこかおかしい。

新しく作ったメソッドを読み込まなかったり、既にないはずのメソッドを参照にしててもコンパイル出来たり。

どうやら原因はherokuにデプロイした際の中間コードとかその辺らしく、、

 

$play clean-all

 

をしてからplay runすると解決しました。

Playで改行コードを<br>に置換

phpならnl3br()を使えば一発ですが。
Javaの拡張クラスにもnl2br()があるみたいですが。

PlayでやるにはscalaのreplaceAll(“対象の文字列”,”置換する文字列”)を利用します。

 

文字列.replaceAll("(\r\n|\r|\n)","<br>")

 

改行コードは環境によって違いますが、
replaceAll()で/r/n、/r、/nを全部<br>に置換します。

ただし。
PlayではデフォルトでHTMLタグがエスケープされるので、HTMLがスケープしないように@Html()で囲う必要が有ります
なので上記の二つを組み合わせて以下の通りに記述します。

 

@Html(文字列.replaceAll("(\r\n|\r|\n)","<br>"))

 

Jqueryを使ってtextareaに入力した改行コードを置き換える場合は、


$(function() {
$("textarea").change( function() {
var txt = $(this).val(txt.replace(/(\r\n|\n|\r)/g,'
'));
});
});

-メモ-

scalaでリストの大きさを調べるのは .size()
phpのcount()に相当。

Play frameworkのCSRF対策

デフォルトだとCRSF余裕なので対策。

環境
・Play 2.2.1
・jDK 1.7

なぜかCRSFのライブラリはデフォルトでは入ってなかったので追加。

build.sbtにfilters,を追加。

libraryDependencies ++= Seq(
//省略
filters,
//省略
)

それから依存関係を解決する為にterminalでplay reload , play update と順次実行。
以上でコンパイルは問題ないけど、eclipseでは反映されないのでplay eclipseを実行。
これでeclipseでもplay.filtersが追加される。

あとはGlobal.javaにフィルタを定義。
これは公式通り→http://www.playframework.com/documentation/2.2.x/JavaCsrf

import play.GlobalSettings;
import play.api.mvc.EssentialFilter;
import play.filters.csrf.CSRFFilter;

public class Global extends GlobalSettings {
//省略
@Override
public Class[] filters() {
return new Class[]{
CSRFFilter.class
};
}
//省略
}

あとは

@import helper._
@form(CSRF(ポスト先のアドレス)) {
//省略
}

とすれば完了。
actionにTokenが付加される