Created
April 23, 2011 17:09
-
-
Save mix3/938782 to your computer and use it in GitHub Desktop.
Mojolicious::Lite + Teng + SNBinder + Xslate (+ SQLite/OnMemory)でCRUDアプリ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Message; | |
use parent 'Teng'; | |
__PACKAGE__->load_plugin('Pager'); | |
use Class::Method::Modifiers; | |
around delete => sub { | |
my ($orig, $self, $table_name, $delete_condition) = @_; | |
my $update_row_data = { | |
deleted_at => DateTime->now->set_time_zone('Asia/Tokyo'), | |
}; | |
$self->update($table_name, $update_row_data, $delete_condition); | |
}; | |
before insert => sub { | |
my ($self, $table_name, $row_data) = @_; | |
$row_data->{created_at} = DateTime->now->set_time_zone('Asia/Tokyo'); | |
$row_data->{updated_at} = DateTime->now->set_time_zone('Asia/Tokyo'); | |
}; | |
before update => sub { | |
my ($self, $table_name, $update_row_data, $update_condition) = @_; | |
if (!$update_row_data->{deleted_at}) { | |
$update_row_data->{updated_at} = DateTime->now->set_time_zone('Asia/Tokyo'); | |
} | |
}; | |
1; | |
package Message::Schema; | |
use Teng::Schema::Declare; | |
use DateTime::Format::MySQL; | |
table { | |
name 'message', | |
pk 'id', | |
columns qw( | |
id | |
message | |
created_at | |
updated_at | |
deleted_at | |
); | |
deflate qr/_at$/ => sub { | |
DateTime::Format::MySQL->format_datetime(shift); | |
}; | |
inflate qr/_at$/ => sub { | |
DateTime::Format::MySQL->parse_datetime(shift); | |
}; | |
}; | |
1; | |
package main; | |
use utf8; | |
use Mojolicious::Lite; | |
plugin 'xslate_renderer'; | |
use Devel::KYTProf; | |
my $model = Message->new( | |
dbh => DBI->connect( | |
'dbi:SQLite:dbname=:memory:', '', '', | |
{ | |
RaiseError => 1, | |
PrintError => 0, | |
AutoCommit => 1, | |
sqlite_unicode => 1, | |
} | |
) | |
); | |
$model->do(q{ | |
CREATE TABLE IF NOT EXISTS message ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
message TEXT NOT NULL, | |
created_at DATETIME NOT NULL, | |
updated_at DATETIME NOT NULL, | |
deleted_at DATETIME | |
) | |
}); | |
get '/' => sub{ | |
my $self = shift; | |
$self->render( | |
handler => 'tx', | |
); | |
} => 'index'; | |
get '/edit/:id' => sub { | |
my $self = shift; | |
my $itr = $model->search_named(q{ | |
SELECT * FROM message WHERE id = :id AND deleted_at IS NULL | |
}, {id => $self->param('id')}); | |
my $result = $itr->next; | |
return $self->render( | |
handler => 'tx', | |
template => 'error', | |
message => '該当メッセージが見つからないか、既に削除されています' | |
) if !$result; | |
$self->render( | |
handler => 'tx', | |
id => $result->get_column('id'), | |
message => $result->get_column('message') | |
); | |
} => 'edit'; | |
post '/create' => sub { | |
my $self = shift; | |
return $self->render( | |
handler => 'tx', | |
template => 'error', | |
message => 'メッセージを入力してください' | |
) if !$self->param('message'); | |
$model->insert('message', { | |
message => $self->param('message'), | |
}); | |
$self->redirect_to('index'); | |
}; | |
post '/update' => sub { | |
my $self = shift; | |
return $self->render( | |
handler => 'tx', | |
template => 'error', | |
message => 'メッセージを入力してください' | |
) if !$self->param('message'); | |
$model->update('message', | |
{ | |
message => $self->param('message'), | |
}, | |
{ | |
id => $self->param('id'), | |
} | |
); | |
$self->redirect_to('index'); | |
}; | |
get '/delete/:id' => sub { | |
my $self = shift; | |
$model->delete('message', { | |
id => $self->param('id'), | |
}); | |
$self->redirect_to('index'); | |
}; | |
get '/show/:id' => sub { | |
my $self = shift; | |
my $itr = $model->search_named(q{ | |
SELECT * FROM message WHERE id = :id AND deleted_at IS NULL | |
}, {id => $self->param('id')}); | |
my $row = $itr->next; | |
my $result = !$row ? {} : $row->get_columns; | |
$self->render('json' => $result); | |
}; | |
get '/list' => sub { | |
my $self = shift; | |
my $page = $self->param('page') || 1; | |
my ($rows, $pager) = $model->search_with_pager( | |
'message', | |
{ | |
deleted_at => \'IS NULL', | |
}, | |
{ | |
order_by => 'id DESC', | |
page => $page, | |
rows => 3, | |
} | |
); | |
my $result = []; | |
foreach my $row (@$rows) { | |
push @$result, $row->get_columns; | |
} | |
$self->render('json' => $result); | |
}; | |
app->start; | |
__DATA__ | |
@@ base.tx | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> | |
<script src="http://www.google.com/jsapi" type="text/javascript"></script> | |
<script type="text/javascript">//<![CDATA[ | |
google.load('jquery', '1.4.4'); | |
//]]></script> | |
<script src="https://github.com/snakajima/SNBinder/raw/master/snbinder-0.5.3.js" type="text/javascript"></script> | |
<title>Mojolicious::Lite + Teng + SNBinder + Xslate (+ SQLite/OnMemory)</title> | |
</head> | |
<body> | |
: block content -> { } | |
</body> | |
</html> | |
@@ form.tx | |
<form method="post" action="<: $path :>"> | |
: if ($id) { | |
<input type="hidden" name="id" value="<: $id :>"> | |
: } | |
<p><textarea name="message" cols="50" rows="10" ><: $message :></textarea></p> | |
<p><input type="submit" /></p> | |
</form> | |
@@ index.html.tx | |
: cascade base | |
: override content -> { | |
<script type="text/javascript">//<![CDATA[ | |
$(document).ready(function(){ | |
var template = "<hr /><p>$(.message)</p><p>[<a href=\"/edit/$(.id)\">編集</a>][<a href=\"/delete/$(.id)\">削除</a>]</p>"; | |
SNBinder.get('/list', null, true, function(json){ | |
$('#list').html(SNBinder.bind_rowset(template, json)); | |
}); | |
}); | |
//]]></script> | |
: include form { path => "/create" } | |
<div id="list" /> | |
: } | |
@@ edit.html.tx | |
: cascade base | |
: override content -> { | |
: include form { path => "/update", message => $message } | |
: } | |
@@ error.html.tx | |
: cascade base | |
: override content -> { | |
ERROR: <: $message :> | |
: } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment