Skip to content

Instantly share code, notes, and snippets.

@mix3
Created April 23, 2011 15:51
Show Gist options
  • Save mix3/938719 to your computer and use it in GitHub Desktop.
Save mix3/938719 to your computer and use it in GitHub Desktop.
Mojolicious::Lite+Teng+SNBinder(+SQLite/In-Memory)でCRUDアプリ
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;
use Devel::KYTProf;
Devel::KYTProf->add_prof('Message', 'search');
Devel::KYTProf->add_prof('Message', 'search_named');
Devel::KYTProf->add_prof('Message', 'search_by_sql');
Devel::KYTProf->add_prof('Message', 'single');
Devel::KYTProf->add_prof('Message', 'insert');
Devel::KYTProf->add_prof('Message', 'update');
Devel::KYTProf->add_prof('Message', 'delete');
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;
} => '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(template => 'error', message => '該当メッセージが見つからないか、既に削除されています') if !$result;
$self->render(
id => $result->get_column('id'),
message => $result->get_column('message')
);
} => 'edit';
post '/create' => sub {
my $self = shift;
return $self->render(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(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__
@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
<head>
<meta charset="<%= app->renderer->encoding %>">
<%= javascript 'http://www.google.com/jsapi' %>
<%= javascript begin %>
google.load('jquery', '1.4.4');
<%= end %>
<%= javascript 'https://github.com/snakajima/SNBinder/raw/master/snbinder-0.5.3.js' %>
<title>Mojolicious::Lite + Teng + SQLite(OnMemory) + SNBinder</title>
</head>
<body><%= content %></body>
</html>
@@ index.html.ep
% layout 'default';
<%= javascript begin %>
$(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));
});
});
<%= end %>
<form method="post" action="<%= url_for('create') %>">
<p><textarea name="message" cols="50" rows="10" ></textarea></p>
<p><input type="submit" /></p>
</form>
<div id="list" />
@@ edit.html.ep
% layout 'default';
<form method="post" action="<%= url_for('update') %>">
<input type="hidden" name="id" value="<%= $id %>" />
<p><textarea name="message" cols="50" rows="10" ><%= $message %></textarea></p>
<p><input type="submit" /></p>
</form>
@@ error.html.ep
% layout 'default';
ERROR: <%= $message =>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment