CodeZine(コードジン)

特集ページ一覧

初めてのCatalyst入門(7)
モデルを使ったプログラミング

ブックマークの情報をデータベースに保存する

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/02/04 14:00
目次

コントローラの実装

 ブックマークアプリケーションでは次のパスを定義します。ブックマークエントリのIDをパスに含めたいので、Chainedアクションを使って実装してみましょう。

定義するURLのパス
パス 説明
/ ブックマークエントリの一覧表示
/add ブックマークエントリの追加
/*/jump 登録されたURLへリダイレクト
/*/edit ブックマークエントリの編集
/*/delete ブックマークエントリの削除

 まずは一覧表示とエントリの追加を行うアクションを見ていきます。

[リスト9]Root.pmの一部(一覧表示/エントリ追加)
package Bookmark::Controller::Root;
# 省略
# (1)一覧表示
sub index :Path :Args(0) {
  my ( $self, $c ) = @_;
  $c->stash->{entries} = [$c->model('BookmarkDB::Entry')->all];
}
# (2)ブックマークエントリの追加
sub add :Local :Args(0) {
  my ( $self, $c ) = @_;
  if ($c->req->method eq 'POST') {
    # パラメータの取得
    my $url = $c->req->params->{url};
    my $title = $c->req->params->{title};
    my $comment = $c->req->params->{comment};
    # パラメータのチェック
    if ($url eq '' || $title eq '') {
      $c->stash->{template} = 'invalid_params.tt';
    } else {
      # データベースに新しいエントリを登録
      $c->model('BookmarkDB::Entry')->create({
        url => $url,
        title => $title,
        comment => $comment
        });
      $c->res->redirect('/', 303);
    }
  }
}
(1)一覧表示

 indexアクションでは、データベースからすべてのレコードを取得し、配列としてStashに渡しています。index.ttをテンプレートとして、エントリのURL一覧情報をレンダリングします。

(2)ブックマークエントリの追加

 addアクションでは、HTTPのPOSTメソッドで呼び出された場合にパラメータから受け取ったURLなどの情報をデータベースに登録し、GETメソッドなどで呼び出された場合には、add.ttをテンプレートとしてレスポンスを表示します。

 Entryテーブルの定義では、URLとTitleはNOT NULL制約がついているので、パラメータから受け取った値が空の場合には、invalid_params.ttを表示するようにしています。

 そして、URLとTitleが空でない場合には$c->model('BookmarkDB::Entry')->create()メソッドに各カラムの名前とパラメータの値をセットしてデータベースに登録しています。登録に成功したらindexアクションにリダイレクトしています。

 次にエントリIDにより指定される、ブックマークエントリの編集、削除、リダイレクトなどを実装したアクションを見ていきます。この部分はChainedアクションを使用しています。Chainedアクションについては第5回の記事を参照ください。

[リスト10]Root.pmの一部(エントリURLへのリダイレクト/編集/削除)
package Bookmark::Controller::Root;
# 省略
# (1)パスに含まれるエントリIDをStashに登録
sub capture_entry :Chained('/') :PathPart('') :CaptureArgs(1) {
  my ( $self, $c, $entry_id ) = @_;
  if (my $entry = $c->model('BookmarkDB::Entry')->find($entry_id)) {
    $c->stash->{entry} = $entry;
  } else {
    $c->stash->{template} = 'not_found.tt';
  }
}
# (2)エントリのURLにリダイレクト
sub jump_entry :Chained('capture_entry') :PathPart('jump') :Args(0) {
  my ( $self, $c ) = @_;
  my $entry = $c->stash->{entry};
  # counterを1増やして更新
  $entry->counter($entry->counter + 1);
  $entry->update;
  $c->res->redirect($entry->url);
}
# (3)エントリの編集
sub edit_entry :Chained('capture_entry') :PathPart('edit') :Args(0) {
    my ( $self, $c ) = @_;
    my $entry = $c->stash->{entry};
    if ($c->req->method eq 'POST') {
	my $url = $c->req->params->{url};
	my $title = $c->req->params->{title};
	my $comment = $c->req->params->{comment};
	if ($url eq '' || $title eq '') {
	    $c->stash->{template} = 'invalid_params.tt';
	} else {
	    $entry->url($url);
	    $entry->title($title);
	    $entry->comment($comment);
	    $entry->update;
	    $c->res->redirect('/', 303);
	}
    }
}
# (4)エントリの削除
sub delete_entry :Chained('capture_entry') :PathPart('delete') :Args(0) {
  my ( $self, $c ) = @_;
  my $entry = $c->stash->{entry};
  if ($c->req->method eq 'POST') {
    # データベースから削除
    $entry->delete;
    $c->res->redirect('/', 303);
  }
}
(1)パスに含まれるエントリIDをStashに登録

 capture_entryアクションでは、パスに含まれるエントリIDをキーにして、データベースから検索した結果が存在すればStashに登録しています。存在しないエントリIDが渡された場合には、not_found.ttをテンプレートとしてレスポンスを表示します。

(2)エントリのURLにリダイレクト

 jump_entryアクションでは、エントリとして登録したURLにリダイレクトするのですが、その際に何回選択したかを表すcounterの値を1だけ増やしています。Stashから取得したEntryオブジェクトに値を更新した場合、それをデータベースに反映させるには、updateメソッドを呼び出します。

(3)エントリの削除

 delete_entryアクションではエントリの削除を実装してます。POSTメソッドで呼び出された場合に限り、Stashに登録されているEntryオブジェクトに対して削除を実行するdeleteメソッドを呼び出し、GETメソッドなどから呼び出された場合には、削除の確認を行うためにdelete_entry.ttをレンダリングして表示します。

 エントリの編集を扱うedit_entryアクションについてはサンプルコードをご覧ください。

ビューの実装

 ブックマークアプリケーションではCatalyst::View::TTのテンプレートファイルを6つ作成しました。紙面の都合上、具体的なコード解説は省きますので、詳細は記事に添付されているサンプルファイルを参照してください。

ビューテンプレートファイル
テンプレートファイル名 説明
index.tt 一覧表示用テンプレート
add.tt エントリの追加フォームを表示するテンプレート
edit_entry.tt エントリの編集フォームを表示するテンプレート
delete_entry.tt エントリの削除フォームを表示するテンプレート
invalid_params.tt 不正なパラメータを受け取った場合に表示するテンプレート
not_found.tt 指定されたエントリが存在しない場合に表示するテンプレート

 この中で、add.tt、edit_entry.tt、delete_entry.ttはHTTPのGETメソッドで呼び出された場合に使用しています。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:Webアプリケーションフレームワーク「Catalyst」入門

もっと読む

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 花田 善仁(ハナダ ヨシヒト)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5