木曜日, 8月 09, 2007

[Ruby][Rails]InputDrawとrailsで作る手書き掲示板

InputDrawとrailsを使って手書き掲示板を作成してみました。InputDrawとは手書き可能なフォームを簡単に作成できるライブラリです。下記のような手書きキャンバスを作成できます。



scaffoldで雛型作成


まずはscaffoldで雛型を作成します。

rails inputdraw
cd inputdraw
./script/generate scaffold_resource post title:string nickname:string comment:text image:string svg:text created_at:datetime updated_at:datetime


データベース準備


inputdraw_developmentというデータベースを作成しておき、マイグレーションを実行します。

rake db:migrate


file_columnプラグインのインストール


画像アップロード処理にはfile_columnプラグインを利用します。これを使うとアップロード処理と、レコードとファイルパスの関連付けを自動でおこなってくれます

./script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk


InpudDrawのインストール


サイトからファイルをダウンロードし、public/javascriptsディレトリに配置します。
|-- javascripts
| |-- inputdraw
| | |-- inputdraw.free-non-commercial.1.2.swf
| | |-- inputdraw.js
| | `-- swfobject.js


ImageSizeのインストール


キャンバスのサイズは画像サイズから求めることにしました。
file_columではRMagickを使って画像を簡単に加工できるようになっていますが、今回はサイズが欲しいだけだったのでImageSizeを利用しました。
gem install imagesize


テンプレートの編集


app/view/layout/posts.rhtml

InputDrawに必要なファイルを読み込みます
<%= javascript_include_tag 'inputdraw/swfobject' %>
<%= javascript_include_tag 'inputdraw/inputdraw' %>


app/view/layout/new.rhtml
Imageをfile_fieldに変更し、フォームタイプをmultipartにします。
svgとcreated_at,updated_atはとりあえず削除します。
<% form_for(:post, :url => posts_path, :html => { :multipart => true }) do |f| %>

<b>Image</b><br />
<%= f.file_field :image %>


app/view/posts/index.rhtml
イメージの部分をタグに置き換えます。svgは表示しないので削除します。
 <td><%= image_tag url_for_file_column(post, "image"), :height => 150 %></td>


app/view/posts/show.rhtml
svgの部分をInputDrawのキャンバスにする要素で置き換えます。表示用に使用したいのでここではsrc要素を指定しています。
imageタグの部分は削除します。
<p>
<b>Svg:</b>
<div id="place"></div>

</p>

<!-- 末尾に追加 -->
<script type="text/javascript">
//<[![CDATA
new InputDraw("/javascripts/inputdraw/inputdraw.free-non-commercial.1.2.swf", "place",

{src_svg:"<%=h @post.svg %>",
width:"<%= @post.image_width %>",
height:"<%= @post.image_height %>",

animation:60,
background_image: '<%= url_for_file_column(@post, "image") %>'});
//]]>
</script>


app/view/posts/edit.rhml
svgのテキストエリアは非表示にします。変わりにキャンバス用の要素とInputDrawのコードを追加します。編集用に使う場合はid要素でsvgデータを保持している入力コントロールのIDを指定します。

<div id="place"></div>

<div style="visibility:hidden; display:none">

<%= f.text_area :svg %>
</div>

<!-- 末尾に追加 -->
<script type="text/javascript">

//<[![CDATA
new InputDraw("/javascripts/inputdraw/inputdraw.free-non-commercial.1.2.swf", "place",
{id:"post_svg",

width:"<%= @post.image_width %>",
height:"<%= @post.image_height %>",
animation:60,

background_image: '<%= url_for_file_column(@post, "image") %>'});
//]]>
</script>


モデルの編集


app/models/post.rb
file_columnと、ImageSizeのコードを追加します。

require 'rubygems'
require 'image_size'

class Post < ActiveRecord::Base

file_column :image

def image_width
image_file ? image_file.get_width : 0
end

def image_height
image_file ? image_file.get_height : 0
end

def image_file
if (image && !@image_file )
open(image ,"rb") do |img|
@image_file = ImageSize.new(img)
end

end
@image_file
end
end



以上で完成です。あとはサーバを起動してhttp://localhost:3000/postsにアクセスするだけです。

参考書籍



Railsを学ぶにはやはりRails開発者であるDavid Heinemeier Hanssonの著書がオススメです。前半はショッピングカートを題材にした実践的なWebアプリケーションのチュートリアル、後半はActiveRecordなど各コンポーネントの詳細説明とRailsの基本から詳細までが網羅された内容となっています。また、ところどころにある"David曰く"の囲みが面白く、例えば「テーブル名はなぜ複数形にするべきなのか?」といった内容に
テーブル名を複数形にしておくことで、Select a Product from products.(商品テーブルから商品を一つ選択してください)という文章が違和感なく理解できるようになります。
と回答されていたりと、Railsがなぜそういった設計にいたったのかという経緯が解説されていたりします。



参考


0 件のコメント: