「Ruby OnRails と Ajax」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
<p align="left"><font size="2"><strong>【参考文献】:AJAX HACKS 6章
Hacks45-52(p207~)</strong></font></p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">MVCアーキテクチャ</font></h2>
<p align="left">
MVCとはデザインパターンの一種で、アプリケーションの構成を、Model、View、Controllerというコンポーネントに分けて設計する手法を言う。</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">Ruby On
Rails のインストール</font></h2>
<p align="center">編集中。。。あまりここに時間を割きたくないな。ぼそ</p>
<p align="center">ここでは、InstantRails-1.7-win.zipを導入して使います。</p>
<p align="center"> </p>
<hr /><h2 align="center"><font style="background-color:rgb(204,153,255);" size="6">Rails アプリの作成</font></h2>
<p align="left"><strong><u>1.開発環境</u></strong></p>
<p align="left">始める前に、念のため開発に使用するマシンのスペックを調べておきます。</p>
<p align="left">Windows XP SP2 であれば、まあ問題ないでしょう。今回はWindows2000でやってみます。</p>
<p align="left">ちなみに、マシンスペックの調べ方は、コマンドで「<strong>dxdiag</strong>」</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>dxdiag</strong></font></p>
</blockquote>
<p align="left">今回の開発環境のサンプル)</p>
<p align="left"><font size="1">------------------<br />
System Information<br />
------------------<br />
Time of this report: 10/16/2008, 09:52:20<br />
Machine name: HIDE2000<br />
Operating System: Windows 2000 Professional (5.0, Build 2195) Service Pack
4<br />
Language: Japanese (Regional Setting: Japanese)<br />
System Manufacturer: VMware, Inc.<br />
System Model: VMware Virtual Platform<br />
BIOS: Default System BIOS<br />
Processor: Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz, ~2.4GHz<br />
Memory: 724MB RAM<br />
Page File: 408MB used, 1049MB available<br />
Windows Dir: C:\WINNT<br />
DirectX Version: DirectX 9.0c (4.09.0000.0904)<br />
DX Setup Parameters: Not found<br />
DxDiag Version: 5.03.0001.0904 32bit Unicode</font></p>
<p align="left"><font size="3"><strong>【補足:開発支援の為のIDE Tool】</strong></font></p>
<p align="left"><font size="3">開発支援の為のIDEToolとして、<strong>eclipse</strong>か<strong>Aptana</strong>か<strong>NetBeans</strong>などを利用すると便利だと思います。</font></p>
<p align="left"><font size="3">今回は「<strong>eclipse</strong>」に「<strong>Aptana</strong>」プラグイン、「<strong>RadRails</strong>」プラグインを仕込んで使います。(<a href="#ide_comment01">※</a>)</font></p>
<p align="left"><a class="FCK__AnchorC FCK__AnchorC FCK__AnchorC FCK__AnchorC FCK__AnchorC" id="ide_comment01" name="ide_comment01"><font size="2"><strong>※)</strong></font></a><font size="2"><strong>手っ取り早く環境を構築するには?</strong></font></p>
<p align="left"><font size="2">これらが全部そろった「<strong>pleiades-all-in-one-ultimate_20081006.zip</strong>」がお勧めです。(=>ダウンロードは<a href="http://mergedoc.sourceforge.jp/"><font color="#FF00FF"><strong>こちら</strong></font></a>から。Eclipse
3.4.1
Ganymedeのultimateがお勧めです。ちなみに3.3.1のほうにはultimateでも今回使いたいRadRailsのプラグインが入ってませんでした。。。)</font></p>
<p align="left"><font size="2"><strong>※) eclipse 3.2.1 に
RadRailsプラグインを追加する方法</strong></font></p>
<table style="font-size:10pt;width:500px;" cellspacing="0" cellpadding="0" border="0"><tbody style="font-size:10pt;"><tr style="font-size:10pt;"><td class="bg_01" style="font-size:10pt;background-color:rgb(225,225,225);" align="center"><br class="Apple-interchange-newline" /><img class="dummy" style="border-right:0px;border-top:0px;font-size:10pt;border-left:0px;width:1px;border-bottom:0px;height:1px;" alt="" src="http://www19.atwiki.jp/_fckeditor2.4.2-base_015flash1.css/editor/skin/dummy.gif" /></td>
<td class="bg_02" style="font-size:10pt;background-color:rgb(255,255,255);" valign="middle" align="left">
<div class="padding_s lh_120" style="padding-right:5px;padding-left:5px;font-size:10pt;padding-bottom:5px;line-height:120%;padding-top:5px;">
<p>AptanaプラグインとRailsプラグインのインストール<br style="font-size:10pt;" />
Eclipseを起動し、「ヘルプ」→「ソフトウェアの更新」→「検索してインストール」を選びます。<br style="font-size:10pt;" />
ダイアログボックスが出たら「新規フィーチャーを探す」を選びます。<br style="font-size:10pt;" />
アップデートサイト選択画面で「新規リモート」を選びます。<br style="font-size:10pt;" />
ここでは次の2つのサイトを登録します。<br style="font-size:10pt;" />
・<a style="border-right:0px;border-top:0px;font-size:10pt;border-left:0px;color:rgb(75,158,247);border-bottom:0px;" target="_blank" href="http://update.aptana.com/install/3.2/">http://update.aptana.com/install/3.2/</a><br style="font-size:10pt;" />
・<a style="border-right:0px;border-top:0px;font-size:10pt;border-left:0px;color:rgb(75,158,247);border-bottom:0px;" target="_blank" href="http://update.aptana.com/install/rails/3.2/">http://update.aptana.com/install/rails/3.2/</a><br style="font-size:10pt;" />
1つ目がAptana本体、2つ目がAptanaのRailsプラグインになります。<br style="font-size:10pt;" /><br style="font-size:10pt;" />
リモートサイトを2つ登録し終わったら、「次へ」をクリックし、<br style="font-size:10pt;" />
以降は通常の更新機能と同様に操作して、インストールを行います。<br style="font-size:10pt;" /><br style="font-size:10pt;" />
Railsパースペクティブを開く<br style="font-size:10pt;" />
プラグインのインストールが終わり、Eclipseを再起動したら、<br style="font-size:10pt;" />
Railsパースペクティブを開きます。<br style="font-size:10pt;" />
「ウィンドウ」→「パースペクティブを開く」→「その他」の中に<br style="font-size:10pt;" />
「Rails」というパースペクティブがあるので、これを選択します。</p>
<p>ここを参考にしました。<br style="font-size:10pt;" /><br style="font-size:10pt;" /><a style="border-right:0px;border-top:0px;font-size:10pt;border-left:0px;color:rgb(75,158,247);border-bottom:0px;" target="_blank" href="http://blog.codezine.jp/editor/2007/06/aptana_eclipseruby_on_rails_1.php">http://blog.codezine.jp/editor/2007/06/aptana_eclipseruby_on_rails_1.php</a><br style="font-size:10pt;" /><br style="font-size:10pt;" /><font color="#FF0000">ちなみに、3.3.x だとうまくいきません。</font>3.3用のURLもどこかにあると思いますが、</p>
<p>それは調べていません。</p>
</div>
</td>
</tr></tbody></table><p align="left"><strong><u>2.Railsのヴァージョン</u></strong></p>
<p align="left">Railsの開発の場合、特にヴァージョンの組み合わせは重要です。</p>
<p align="left">
今回は、<strong>InstantRails-1.7-win.zip</strong>をインストールして準備した環境なので、「<strong>Rails
1.2.3</strong>」になります。このヴァージョンが現在最も情報量が豊富です。(=>ダウンロードは<a href="http://rubyforge.org/frs/?group_id=904"><font color="#FF00FF"><strong>こちら</strong></font></a>から。)</p>
<p align="left"><font size="2">※ <strong>ruby</strong>の最新の1.9などは1.8.6に比べてだいぶ変わったようですし、フレームワークである<strong>rails</strong>もヴァージョンが<strong>1.2.X系</strong>と<strong>2.X系</strong>では<strong>scaffold</strong>などかなりやり方が異なります。パッケージ管理Toolである<strong>gem</strong>なども実は<strong>gem</strong>自体のヴァージョンによりインポートできるモジュールのヴァージョンが違ったりと、手抜かりがあるとなかなか手こずりますので注意しましょう。</font></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>ruby
-v<br /></strong></font>ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]</p>
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>gem
env<br /></strong></font>RubyGems Environment:<br />
- VERSION: 0.9.2 (0.9.2)<br />
- INSTALLATION DIRECTORY: C:/InstantRails/ruby/lib/ruby/gems/1.8<br />
- GEM PATH:<br />
- C:/InstantRails/ruby/lib/ruby/gems/1.8<br />
- REMOTE SOURCES:<br />
-<a href="http://gems.rubyforge.org">http://gems.rubyforge.org</a></p>
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>rake
--version</strong></font><br />
rake, version 0.7.2</p>
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>rails
--version</strong></font><br />
Rails 1.2.3</p>
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>mysql
--version</strong></font><br />
mysql Ver 14.12 Distrib 5.0.27, for Win32 (ia32)</p>
</blockquote>
<p align="left"> </p>
<p align="left">・ <strong>もうひとつのヴァージョンの調べ方</strong></p>
<p align="left">
ひとつひとつのコマンドを打ち込んでヴァージョンを調べてもいいけれども、Railsの場合たくさんのパッケージやモジュールで構成されていて調べるのはいささか面倒です。そこで一発でこれらを調べるコマンドを紹介します。ただし、これはプロジェクト内部の<strong>aboutコマンド</strong>なので、少なくとも後述するプロジェクトを何かひとつ作成してから、実行してください。</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><span class="Apple-style-span" style="word-spacing:0px;font:13px/15px 'ms pgothic';text-transform:none;color:rgb(51,51,51);text-indent:0px;letter-spacing:normal;border-collapse:separate;">
<font style="background-color:rgb(192,192,192);" face="Arial" color="#000000"><font size="2">// <font color="#FF0000">これはうまくいきません。</font></font></font></span></p>
<p align="left"><span class="Apple-style-span" style="word-spacing:0px;font:13px/15px 'ms pgothic';text-transform:none;color:rgb(51,51,51);text-indent:0px;letter-spacing:normal;border-collapse:separate;">
<font style="background-color:rgb(192,192,192);"><font size="2"><font face="Arial" color="#000000">C:\InstantRails\rails_apps></font><strong>ruby
script/about</strong></font></font></span></p>
<p align="left"><span class="Apple-style-span" style="word-spacing:0px;font:13px/15px 'ms pgothic';text-transform:none;color:rgb(51,51,51);text-indent:0px;letter-spacing:normal;border-collapse:separate;">
<font size="3"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks<strong>>ruby
script/about<br /></strong></font>About your application's environment<br /><strong>Ruby version 1.8.6 (i386-mswin32)<br />
RubyGems version 0.9.2<br />
Rails version 1.2.3</strong><br />
Active Record version 1.15.3<br />
Action Pack version 1.13.3<br />
Action Web Service version 1.2.3<br />
Action Mailer version 1.3.3<br />
Active Support version 1.4.2<br />
Application root C:/InstantRails/rails_apps/hacks<br />
Environment development<br />
Database adapter mysql</font></span></p>
</blockquote>
<p align="left"> </p>
<p align="left"><strong><u>3.作成手順</u></strong></p>
<p align="left">
RailsアプリはDB利用を前提としたWebアプリになるため、Railsの命名規則が重要になってきます。ここら辺は<strong><a href="http://www19.atwiki.jp/hide1227/pages/17.html#DRY">DRY</a></strong>や<strong><a href="http://www19.atwiki.jp/hide1227/pages/17.html#CoC">CoC</a></strong>の思想によるところですが、今回のAjax用のRailsアプリサンプルとして以下の情報をまず収集します。</p>
<ul><li>
<div align="left">プロジェクト名:プロジェクトのルートとなる名前、主にフォルダ管理のため。</div>
</li>
<li>
<div align="left">使用するRDB:MySQL,SQLite3,PostgreSQL,SQL Server,DB2,Oracle</div>
</li>
<li>
<div align="left">DB名:<strong>開発用</strong>、テスト用、リリース用の三種類を用意します。</div>
</li>
<li>
<div align="left">テーブル名:<strong>複数形</strong>小文字英数字</div>
</li>
<li>
<div align="left">モデル名:原則としてテーブル名と関連します。<strong>単数形</strong>のテーブル名</div>
</li>
</ul><p align="left">それでは、今回のAjax用のRailsアプリサンプルの情報を定義していきましょう。</p>
<ul><li>
<div align="left">プロジェクト名:<strong>hacks</strong></div>
</li>
<li>
<div align="left">使用するRDB:<strong>mysql</strong></div>
</li>
<li>
<div align="left">
DB名:<strong>hacks_development,hacks_test,hacks_production</strong></div>
</li>
<li>
<div align="left">テーブル名:<strong>kilowatts</strong></div>
</li>
<li>
<div align="left">モデル名:<strong>Kilowatt</strong></div>
</li>
</ul><p align="left">ここで、一応テーブルの定義も決めておきましょうか。</p>
<p align="left"> </p>
<p align="center"><strong>Kilowattsテーブル定義</strong></p>
<div align="center">
<table cellspacing="1" cellpadding="1" width="200" align="center" border="1"><tbody><tr><td>
<p align="center"> <font size="2">NO</font></p>
</td>
<td>
<p align="center"><font size="2">カラム名 </font></p>
</td>
<td>
<p align="center"><font size="2"> 型</font></p>
</td>
<td>
<p align="center"><font size="2"> NotNull</font></p>
</td>
<td>
<p align="center"><font size="2"> 主キー</font></p>
</td>
</tr><tr><td>
<p align="center"><font size="2"> 1</font></p>
</td>
<td>
<p align="center"><font size="2"> id</font></p>
</td>
<td>
<p align="center"><font size="2">int </font></p>
</td>
<td>
<p align="center"><font size="2">true </font></p>
</td>
<td>
<p align="center"><font size="2">true </font></p>
</td>
</tr><tr><td>
<p align="center"><font size="2"> 2</font></p>
</td>
<td>
<p align="center"><font size="2"> kdate</font></p>
</td>
<td>
<p align="center"><font size="2"> text</font></p>
</td>
<td>
<p align="center"><font size="2"> </font></p>
</td>
<td>
<p align="center"><font size="2"> </font></p>
</td>
</tr><tr><td>
<p align="center"><font size="2"> 3</font></p>
</td>
<td>
<p align="center"><font size="2">kwatts </font></p>
</td>
<td>
<p align="center"><font size="2">int </font></p>
</td>
<td>
<p align="center"><font size="2"> </font></p>
</td>
<td>
<p align="center"><font size="2"> </font></p>
</td>
</tr></tbody></table></div>
<p align="left">DDLファイルを作成するとしたら、以下のようになるかと思います。(<a href="#comment_01">※</a>)</p>
<p align="left">DDL:kilowatts.sql</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left">DROP TABLE IF EXISTS kilowatts;<br />
CREATE TABLE kilowatts (<br />
id MEDIUMINT NOT NULL AUTO_INCREMENT,<br />
kdate TEXT,<br />
kwatts INT,<br />
PRIMARY KEY(id)<br />
);</p>
</blockquote>
<p align="left"><a class="FCK__AnchorC FCK__AnchorC FCK__AnchorC FCK__AnchorC FCK__AnchorC" id="comment_01" name="comment_01"><font size="2">※)</font></a><font size="2">ただし、Railsの作成方法では、このようなDB周りの準備もRailsでサポートされており、具体的には<u><a href="#001_create_kilowatts_2">「<strong>マイグレーション</strong>」という手法を使います</a></u>。ちなみに、この作成方法は<a href="#001_create_kilowatts_2"><font color="#FF0000">Rails
1.2.x 系列とRails 2.x 系列で作成手順が違います</font>。</a>これは追って説明します。</font></p>
<p align="left">【参考】:<a href="http://www.oreilly.co.jp/books/4873113040/"><font color="#FF00FF"><strong>ソースダウンロード</strong></font></a></p>
<p align="left">
ちなみに、このページはUTF8になります。ブラウザで文字化けなどしたらエンコードを変更してみてください。<strong>AjaxHacksSamples.zip</strong>を解凍してサンプルコードを手に入れてください。</p>
<p align="left"><strong>【事前準備】</strong></p>
<p dir="ltr" style="margin-right:0px;" align="left">
InstantRailsでインストールした場合は、<strong>InstantRails.exe
は起動</strong>しておきましょう。起動するとApacheとMySQlが立ち上がります。後ほどRailsからDBを作成したり、テーブルを作成しますが、そのためには今回使用する<strong>MySQLがサービスとして起動</strong>している必要があります。Webサーバは開発モードでは他の(Mongrelサーバ)を使うのでApacheは立ち上げる必要性はないですが、DBの確認作業で、phpMyAdminというToolを使う場合は<strong>Apacheサーバを立ち上げておく</strong>必要があります。</p>
<p dir="ltr" style="margin-right:0px;" align="left">
また、DBにMySQLを使用するのであれば、最初に、<strong>my.ini</strong>ファイルにてDBの文字コード指定をしておきます。以下のソースの<font color="#0000FF">青字部分</font>を追記してください。</p>
<p dir="ltr" style="margin-right:0px;" align="left">
C:\InstantRails\mysql\my.ini</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p dir="ltr" style="margin-right:0px;" align="left">; ----------------------
IMPORTANT ---------------------------;<br />
; ${path} is used to specify Instant Rails installation path. ;<br />
;-------------------------------------------------------------;</p>
<p dir="ltr" style="margin-right:0px;" align="left">[mysqld]<br />
datadir=${path}/mysql/data<br />
basedir=${path}/mysql<br />
bind-address=127.0.0.1<br />
; Uncomment for use on USB key<br />
; skip-innodb<br /><strong><font color="#0000FF">default-character-set=utf8<br />
skip-character-set-client-handshake</font></strong></p>
</blockquote>
<p align="left">ここまで準備すれば、雛形部分の作成は<strong>15分もかからないでしょう</strong>。</p>
<p align="left"><strong>【プロジェクトの作成】</strong></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p dir="ltr" style="margin-right:0px;" align="left">// 1.0
railsアプリのルートフォルダに移動<br />
// InstantRailsでインストールした場合には、その下に「rails_apps」があるはず。そこです。<br /><font style="background-color:rgb(153,204,0);">C:\><strong>cd
C:\InstantRails\rails_apps</strong></font></p>
<p dir="ltr" style="margin-right:0px;" align="left">// 2.0 railsコマンドの実行<br />
// 通常は、Rails 1.2.3 の場合、DBは mysql になります。<br />
// rails hacks<br />
//<br />
// デフォルトじゃないDBシステムを指定するには<br />
// rails hacks -d mysql<br />
// かもしくは、<br />
// rails hacks --database=mysql<br />
//<br /><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>rails
hacks -d mysql</strong></font></p>
</blockquote>
<p align="left"><strong> 【DB作成】</strong></p>
<p align="left">
<strong>DBの作成の仕方</strong>には幾通りかあります。各ベンダーにより簡単なやりかたがそれぞれあるでしょうが、RailsにはrakeコマンドでDB作成Toolを作成することもできます。それを使用すればマルチDBの作成が夢ではないと思いますが、それは次回のテーマに譲ることにして、ここでは、使用するDBをMySQLとした場合、InstantRails導入した際に利用できる<strong>phpMyAdmin</strong>を使用して簡単に作成してしまいましょう。InstantRails.exeが立ち上がっている状態であれば、以下のURLにアクセスできるはずです。</p>
<p align="left"><a href="http://127.0.0.1/mysql/">http://127.0.0.1/mysql/</a></p>
<p align="left">今回作成するDBは三種類です。</p>
<ul><li>
<div align="left"><strong>hacks_development</strong></div>
</li>
<li>
<div align="left"><strong>hacks_test</strong></div>
</li>
<li>
<div align="left"><strong>hacks_production</strong></div>
</li>
</ul><p align="left">
これは先ほどのプロジェクトの作成の際に自動で命名規約されているDB名です。もちろんこれを変更することも可能ですが、それは以下のリソースに定義してあります。まず素直に自動生成されたソースを覗いてみましょう。</p>
<p align="left">
C:\InstantRails\rails_apps\hacks\config\<strong>database.yml</strong></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left">development:<br />
adapter: mysql<br />
database:<strong>hacks_development</strong><br />
username: root<br />
password:<br />
host: localhost</p>
<p align="left">test:<br />
adapter: mysql<br />
database:<strong>hacks_test</strong><br />
username: root<br />
password:<br />
host: localhost</p>
<p align="left">production:<br />
adapter: mysql<br />
database:<strong>hacks_production</strong><br />
username: root<br />
password:<br />
host: localhost</p>
</blockquote>
<p align="left">
今回はここでデフォルトに指定されているDB名をそのまま使用することにします。DB名を変えたければ、[database:]の値を変えればいいでしょう。</p>
<p align="left">ちなみに、今回はMySQLなのでこのまま使用しますが、<font color="#FF0000">Oracleなどの場合は、DBを複数作成するよりも、スキーマを3つ用意したほうが現実的</font>だと思われます。</p>
<p align="left"><strong>【補足:文字コード問題】</strong></p>
<p align="left">
<strong>my.ini</strong>に指定したように、この<strong>database.yml</strong>ファイルでも文字コードを指定します。3つのDB定義の最後の要素にそれぞれ以下を追加します。(※MySQL使用時には必要ですがOracle使用する場合は必要がないようです。)</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"> <strong>encoding: utf8</strong></p>
</blockquote>
<p align="left">
また、文字コード問題というと、DBの文字コードだけでなく、<strong>Ruby自体の文字コード指定をする必要があります</strong>。<br />
今回のRailsアプリの文字コード指定は、「<strong>environment.rb</strong>」というファイルでの最初の行で設定します。<br /><br />
例)文字コードをUTF-8に指定するやりかた。</p>
<div align="left">
<blockquote><strong>$KCODE = "UTF8"<br /></strong></blockquote>
</div>
<p align="left"><br />
もしくは、</p>
<div align="left">
<blockquote>$KCODE = 'u'<br /></blockquote>
</div>
<p align="left"><br />
どちらも同じ意味です。最初の 1
バイトしか読み取っていないようです。しかも大文字小文字すら関係ないようです。でも自分としては可読性を考慮してUTF8と記述したいところです。<br /><br />
【参考サイト】<br /><a href="http://www.ruby-lang.org/ja/man/html/_C1C8A4DFB9FEA4DFCAD1BFF4.html">http://www.ruby-lang.org/ja/man/html/_C1C8A4DFB9FEA4DFCAD1BFF4.html</a></p>
<p align="left"> </p>
<p align="left">では、phpMyAdminのサイトにてこれらの3つのDBを作成してみましょう。</p>
<p align="left">確認は、phpMyAdminでもできますが、コンソールからDBが作成されたことを確認してみます。</p>
<blockquote>
<p align="left">C:\InstantRails\rails_apps\hacks>mysql -u root<br />
Welcome to the MySQL monitor. Commands end with ; or \g.<br />
Your MySQL connection id is 18 to server version: 5.0.27-community<br /><br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br /><br />
mysql> show databases;<br />
+----------------------------------------+<br />
| Database |<br />
+----------------------------------------+<br />
| information_schema |<br />
|<strong>hacks_development</strong> |<br />
|<strong>hacks_production</strong> |<br />
|<strong>hacks_test</strong> |<br />
+----------------------------------------+<br />
29 rows in set (0.01 sec)<br /><br />
mysql></p>
</blockquote>
<p align="left"> </p>
<p align="left"><strong> 【eclipse へインポート】</strong></p>
<p align="left">この辺で、今後の作業の円滑を図り、eclipseへプロジェクトごとインポートしておきます。</p>
<p align="left"> <img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks002.jpg" /></p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks003.jpg" /></p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks004.jpg" /></p>
<p align="left">プロジェクトを選択</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks005.jpg" /></p>
<p align="left">選択してOK押下</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks006.jpg" /></p>
<p align="left">作成されたことを確認</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks007.jpg" /></p>
<p align="left">プロジェクトをマウントしたら、すかさずeclipseプロジェクト上の文字コードをUTF8に設定する。</p>
<p align="left"> <img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks008.jpg" /></p>
<p align="left"> <img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks009.jpg" /></p>
<p align="center"> </p>
<p align="left"><font size="2"><font size="3"><strong>【テーブルの作成】</strong><br /></font>事前準備してあるテーブル定義書に従い、Rails用のDDLファイルといえる<strong><font style="background-color:rgb(255,255,153);">マイグレーションファイル</font>を作成します</strong>。<br />
作成の手順は、<font color="#FF0000">Rails 1.2.3 と Rails 2.0.2 では微妙に異なります</font>。<br /><br /><strong>Rails 1.2.3</strong>では、<br /></font></p>
<div align="left">
<ol><li><font size="2">ジェネレータの「<strong><font color="#0000FF">migration</font></strong>」サブコマンドにてマイグレーションファイルのスタブを作成して後</font></li>
<li><font size="2">テーブル定義書に従い、マイグレーションファイルの編集</font></li>
<li><font size="2">「<strong>db:migrate</strong>」コマンドを実行する。</font></li>
<li><font size="2">その後、「<strong>scaffold</strong>」を実行し、テーブルに対応するモデルクラスやコントロールクラスのCRUD構成を一気に作成する。</font></li>
</ol></div>
<p align="left"><br /><font size="2">という手順になるが、<strong>Rails 2.0.2</strong>では</font></p>
<div align="left">
<ol><li><font size="2">「<strong>scaffold</strong>」にて、MVCアーキテクチャのすべてのソースを一気に作成する。</font></li>
<li><font size="2">「<strong>db:migrate</strong>」コマンドを実行する。</font></li>
</ol></div>
<p align="left"><br /><font size="2">ただし、その際の<font color="#FF0000">「scaffold」のコマンドオプションの指定の仕方が変わりました。カラム名や型を同時に宣言しなければならなくなりました。</font><br /><br />
ここでは、Railsのヴァージョンは 1.2.3 なので、最初の手続きによるやり方で行う。<br />
ちなみに、eclipse の RadRailsパースペクティブにおいては、generatorというviewが存在し、<br />
そこでコマンドを実行が可能です。<br /><br />
ここでは、コマンドラインでの実行方法を紹介します。(Rails 1.2.3の場合)<br /></font></p>
<div align="left">
<blockquote>
<p><font size="3"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>ruby
script/generate migration create_kilowatts</strong></span><br />
create db/migrate<br />
create db/migrate/<strong><font color="#0000FF">001_create_kilowatts.rb</font></strong><br /><br />
C:\InstantRails\rails_apps\hacks></font></p>
</blockquote>
</div>
<p align="left">ちなみに、Rails
2.0.2の場合は <strong>migration</strong>ではなく、ここでいきなり<strong>scaffold </strong>していいです。</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>ruby
script/generate scaffold kilowatt kdate:text kwatts:integer</strong></span></p>
</blockquote>
<p align="left">では、eclipse に戻って、作業領域をリフレッシュ(F5)した後、編集してみましょう。</p>
<p align="left"><strong><a class="FCK__AnchorC" name="001_create_kilowatts"><font color="#000000" size="3">001_create_kilowatts.rb</font></a>(Rails 1.2.3の場合)</strong></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left">class CreateKilowatts < ActiveRecord::Migration<br />
def self.up<br />
create_table(:kilowatts) do |table|<br /><strong><font color="#0000FF"> table.column :kdate , :text<br />
table.column :kwatts , :integer</font></strong><br />
end<br />
end<br /><br />
def self.down<br />
drop_table :kilowatts<br />
end<br />
end</p>
</blockquote>
<p align="left"><a class="FCK__AnchorC" name="001_create_kilowatts_2"><font color="#000000" size="3"><strong>001_create_kilowatts.rb</strong></font></a><strong>(Rails
2.0.2の場合)</strong></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left">class CreateKilowatts < ActiveRecord::Migration<br />
def self.up<br />
create_table(:kilowatts) do |table|</p>
<p align="left"><font color="#FF0000"><strong> table.text :kdate<br />
table.integer :kwatts</strong></font> <br />
end<br />
end<br /><br />
def self.down<br />
drop_table :kilowatts<br />
end<br />
end</p>
</blockquote>
<p align="left"><strong><font size="2">(※注意)</font></strong></p>
<p align="left"><font size="2"><font color="#FF0000">Rails1.2.3とRails2.0.2の表記の違いに</font>注意してください。また2.0.2の場合、自動生成される「<strong>table.timestamps</strong>」ですが、これはカラムの「<strong><font color="#000000">create_at</font></strong>」と「<strong><font color="#000000">update_at</font></strong>」に相当します。</font></p>
<p align="left">
このマイグレーションファイルはマルチDBに対応した<strong>Rails独自の文法</strong>による記載になります。</p>
<p align="left">非常に便利なものだが、まず各ベンダーのRDBの型との対応に注意しなければなりません。</p>
<p align="left">手元には、<strong>データ型の対応表</strong>が必要になると思われる。</p>
<div align="center">
<table class="style_table" cellspacing="1" align="center" border="0"><tbody><tr><td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">
型</td>
<td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">
説明</td>
<td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">
MySQL</td>
<td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">SQL
Server</td>
<td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">
Oracle</td>
</tr><tr><td class="style_td" style="text-align:left;"><font color="#FF0000"><strong>id</strong></font></td>
<td class="style_td" style="text-align:left;">プライマリキー</td>
<td class="style_td" style="text-align:left;">int(11)</td>
<td class="style_td" style="text-align:left;">int</td>
<td class="style_td" style="text-align:left;">NUMBER(38)</td>
</tr><tr><td class="style_td" style="text-align:left;">:string</td>
<td class="style_td" style="text-align:left;">文字列</td>
<td class="style_td" style="text-align:left;">varchar(255)</td>
<td class="style_td" style="text-align:left;">varchar(255)</td>
<td class="style_td" style="text-align:left;">VARCHAR(255)</td>
</tr><tr><td class="style_td" style="text-align:left;">:text</td>
<td class="style_td" style="text-align:left;">長い文字列</td>
<td class="style_td" style="text-align:left;">text</td>
<td class="style_td" style="text-align:left;">text</td>
<td class="style_td" style="text-align:left;">CLOB</td>
</tr><tr><td class="style_td" style="text-align:left;">:integer</td>
<td class="style_td" style="text-align:left;">整数</td>
<td class="style_td" style="text-align:left;">int(11)</td>
<td class="style_td" style="text-align:left;">int</td>
<td class="style_td" style="text-align:left;">NUMBER(38)</td>
</tr><tr><td class="style_td" style="text-align:left;">:float</td>
<td class="style_td" style="text-align:left;">浮動少数</td>
<td class="style_td" style="text-align:left;">float</td>
<td class="style_td" style="text-align:left;">real</td>
<td class="style_td" style="text-align:left;">NUMBER</td>
</tr><tr><td class="style_td" style="text-align:left;">:decimal</td>
<td class="style_td" style="text-align:left;">精度の高い小数</td>
<td class="style_td" style="text-align:left;">decimal(10,0)</td>
<td class="style_td" style="text-align:left;">decimal(18,0)</td>
<td class="style_td" style="text-align:left;">NUMBER(38)</td>
</tr><tr><td class="style_td" style="text-align:left;">:datetime</td>
<td class="style_td" style="text-align:left;">日時</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;">:timestamp</td>
<td class="style_td" style="text-align:left;">日時(より細かい)</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;">:time</td>
<td class="style_td" style="text-align:left;">時間</td>
<td class="style_td" style="text-align:left;">time</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;">:date</td>
<td class="style_td" style="text-align:left;">日付</td>
<td class="style_td" style="text-align:left;">date</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;">:binary</td>
<td class="style_td" style="text-align:left;">バイナリデータ</td>
<td class="style_td" style="text-align:left;">blob</td>
<td class="style_td" style="text-align:left;">image</td>
<td class="style_td" style="text-align:left;">BLOB</td>
</tr><tr><td class="style_td" style="text-align:left;">:boolean</td>
<td class="style_td" style="text-align:left;">Boolean型</td>
<td class="style_td" style="text-align:left;">tinyint(1)</td>
<td class="style_td" style="text-align:left;">bit</td>
<td class="style_td" style="text-align:left;">NUMBER(1)</td>
</tr><tr><td class="style_td" style="text-align:left;"><font color="#FF0000"><strong>create_at</strong></font></td>
<td class="style_td" style="text-align:left;">マジックフィールド</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;"><font color="#FF0000"><strong>update_at</strong></font></td>
<td class="style_td" style="text-align:left;">マジックフィールド</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr></tbody></table></div>
<p align="center"> </p>
<p align="left">次に「<strong>rake db:migrate</strong>」コマンドを実行する。(ちなみに eclipse の
Rake view からも実行が可能だ。)</p>
<blockquote>
<p align="left"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>rake
db:migrate</strong></span><br />
== CreateKilowatts: migrating
=================================================<br />
-- create_table(:kilowatts)<br />
-> 0.0780s<br />
== CreateKilowatts: migrated (0.0780s)
========================================</p>
</blockquote>
<p align="left"> この時、「<a class="item" href="http://127.0.0.1/mysql/tbl_structure.php?db=hacks_development&table=schema_info&token=ae0c25beaf8dfd210e010a4eab058ced">テーブル:
schema_info</a>」も同時に作成されていることに着目しておこう。これはマイグレーションにおける履歴管理のためのテーブルで、Railsの管理の下、テーブル定義が仕様変更となっても、すぐに反映させたり、また逆に元に戻すことを可能にした仕組みだ。</p>
<p align="left">
この点を踏まえると、Railsを使うならば、マイグレーションなしに勝手にテーブル作成することは好ましくないといえるだろう。</p>
<p align="left"><strong>【テーブル作成の確認】</strong></p>
<blockquote>
<p align="left"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>mysql
-u root</strong></span><br />
Welcome to the MySQL monitor. Commands end with ; or \g.<br />
Your MySQL connection id is 30 to server version: 5.0.27-community<br /><br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br /><br /><span style="background-color:rgb(51,204,204);">mysql><strong>use
hacks_development;</strong></span><br />
Database changed<br /><span style="background-color:rgb(51,204,204);">mysql><strong>show
tables;</strong></span><br />
+-----------------------------+<br />
| Tables_in_hacks_development |<br />
+-----------------------------+<br />
| kilowatts |<br />
|<font color="#0000FF">schema_info</font> |<br />
+-----------------------------+<br />
2 rows in set (0.00 sec)<br /><br />
mysql></p>
</blockquote>
<p align="left"><strong>【足場の作成】</strong></p>
<p align="left">
ここで足場となるMVCアーキテクチャに沿ったソースを自動生成します。そのためのコマンドとして、先ほど紹介した「<strong>scaffold</strong>」というコマンドがあります。</p>
<blockquote>
<p align="left"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>ruby
script/generate scaffold kilowatt</strong></span><br />
exists app/controllers/<br />
exists app/helpers/<br />
create app/views/kilowatts<br />
exists app/views/layouts/<br />
exists test/functional/<br />
dependency model<br />
exists app/models/<br />
exists test/unit/<br />
exists test/fixtures/<br />
create app/models/kilowatt.rb<br />
create test/unit/kilowatt_test.rb<br />
create test/fixtures/kilowatts.yml<br />
create app/views/kilowatts/_form.rhtml<br />
create app/views/kilowatts/list.rhtml<br />
create app/views/kilowatts/show.rhtml<br />
create app/views/kilowatts/new.rhtml<br />
create app/views/kilowatts/edit.rhtml<br />
create app/controllers/kilowatts_controller.rb<br />
create test/functional/kilowatts_controller_test.rb<br />
create app/helpers/kilowatts_helper.rb<br />
create app/views/layouts/kilowatts.rhtml<br />
create public/stylesheets/scaffold.css</p>
</blockquote>
<p align="left"> </p>
<p align="left"> </p>
<p align="left">ここまでで雛形が完成したはずです。</p>
<p align="left"><strong>【動作確認】</strong></p>
<p align="left">
では、早速サーバを起動させてみましょう。WebサーバはRailsでは複数用意されていますが、開発モード時点ではApacheなどは使わないです。(かといって現在あがっているApacheを落とす必要はありません。)簡易サーバとして、<strong>Mongrelサーバ</strong>というものが、ありますので、今回はそれを使用します。</p>
<p align="left">
サーバー起動のやり方は、コマンドラインとeclipseでの起動のさせ方とありますが、ポート番号まで比較的簡単に指定できるeclipse起動のやり方を紹介します。</p>
<p align="left">まず、eclipseにて対象となるプロジェクト(今回の場合は「hacks」)を選択して、Runします。</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks010.jpg" /></p>
<p align="left"> <img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks011.jpg" /></p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks012.jpg" /></p>
<p align="left">
ここでOKを押下すれば、対象のサーバインスタンスが立ち上がるはずなのですが、実際には別のインスタンスが起動してしまうような現象に遭遇しました。ヴァージョンは、3.2.1でも3.4.1でも起こります。なのでその場合は、一旦関係のないサーバインスタンスを停止し、再度Serversヴューにて起動対象のサーバインスタンスを選択して実行してみてください。</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks013.jpg" /></p>
<p align="left">以上のように起動すれば、Webアプリが起動されているはずです。</p>
<p align="left">以下のURLをブラウザで指定してみましょう。</p>
<p align="left">(今回はIP指定しますが、普段の開発ではHOSTはlocalhostか127.0.0.1でかまわないでしょう。)</p>
<p align="left">// 今回のURL<br /><a href="http://192.168.1.29:3008/kilowatts/">http://192.168.1.29:3008/kilowatts/</a><br /><br />
// 通常はデフォルト指定のままなので以下のURL<br /><a href="http://localhost:3008/kilowatts/">http://localhost:3008/kilowatts/</a><br /><a href="http://127.0.0.1:3008/kilowatts/">http://127.0.0.1:3008/kilowatts/</a></p>
<p align="left">ホスト名の次に指定するURIの要素がテーブル名になっていることに着目してください。</p>
<p align="left">
また、デフォルトの入り口が、indexになるのですが、実際にはlist画面にリダイレクトされています。ここは、Railsの仕組みをもう少し追いかけていくことで判明します。</p>
<p align="left"> </p>
<p align="left">とりあえず、ここまでで Railsのアプリの土台部分がが作成できました。</p>
<p align="left"> </p>
<p align="left">おめでとうございます!!</p>
<p> </p>
<hr /><h2 align="center"><font style="background-color:rgb(204,153,255);" size="6">Ajaxライブラリの導入方法</font></h2>
<p align="left">
Ajaxには多数のライブラリが存在しており、現在では生で「<strong>XMLHttpRequest</strong>」オブジェクトを操作することはあまり機会がなくなっているといえるんではないでしょうか。最も有名なライブラリは「<strong>Prototype</strong>」ですが、これはどうやら<strong>Ruby
On Railsがそのルーツ</strong>だそうです。ということで Railsをやるならデフォルトでついてきてます。</p>
<blockquote>
<p align="left"><strong><%= javascript_include_tag<font color="#0000FF">:defaults</font>%></strong></p>
</blockquote>
<p align="left"> この記述でHTMLソースにはどのように変換されているか調べてみると、</p>
<blockquote>
<p align="left"><script
src="/javascripts/<strong>prototype.js</strong>?1224125580"
type="text/javascript"></script><br />
<script src="/javascripts/<strong>effects.js</strong>?1224125580"
type="text/javascript"></script><br />
<script src="/javascripts/<strong>dragdrop.js</strong>?1224125580"
type="text/javascript"></script><br />
<script src="/javascripts/<strong>controls.js</strong>?1224125580"
type="text/javascript"></script><br />
<script src="/javascripts/<strong>application.js</strong>?1224125580"
type="text/javascript"></script></p>
</blockquote>
<p align="left"> でした。</p>
<p align="left">自動生成された
javascriptライブラリをこの一行でロードしています。一番お手軽な書式ですが、必要なものだけを指定したほうが効率がいいでしょう。その場合は、</p>
<blockquote>
<p align="left"><strong><%= javascript_include_tag<font color="#0000FF">"prototype.js"</font>%></strong></p>
</blockquote>
<p align="left">ところで<font color="#FF0000">、このロードの順番は重要です</font>。前後を入れ替えないこと。</p>
<p align="left">逆に言うと、<a class="FCK__AnchorC" id="myjavascript" name="myjavascript"><font color="#FF0000"><strong>自分で定義した
javascript関数</strong></font>は一番最後にロードされる「<strong>application.js</strong>」に入れるべきです。</a></p>
<p align="left"> </p>
<h2 align="center"><font style="background-color:rgb(204,153,255);" size="6">XMLHttpRequestの使い方</font></h2>
<p align="left">XMLHttpRequestの使い方を調べるためにサンプルを作成しましょう。<br />
Railsでは<strong><font color="#FF0000">XMLHttpRequestを生で使わない</font></strong>とはどういうことでしょうか?</p>
<p align="left">
ひとつには、ライブラリ「<strong>prototype.js</strong>」を内部で利用しているため、そのラッパークラスを通じて操作できるためです。</p>
<p align="left">しかし、Railsの場合は、さらにそれをラッピングしたメソッドが存在し、それを利用することができます。<br /><br />
まず、それを確かめるためのコントロールとヴューを作成したいと思います。<br />
ここで、今回はDBを使わないので、あえてscaffoldはせずに、generateではコントローラだけを指定してモデルは作成しないことにします。必要なのはアクションとその画面のみ…ということで、このようなコマンドを実行してみます。<br /><br />
C(コントローラ):<strong>hacks</strong><br />
V(ヴュー):<strong>monitor</strong></p>
<div align="left">
<blockquote><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>ruby
script/generate controller hacks</strong><br /></font> exists
app/controllers/<br />
exists app/helpers/<br />
create app/views/hacks<br />
exists test/functional/<br />
create app/controllers/hacks_controller.rb<br />
create test/functional/hacks_controller_test.rb<br />
create app/helpers/hacks_helper.rb<br /></blockquote>
</div>
<p align="left">
コントローラですが、hacks_controller.rb はJavaでいえばサーブレットみたいなものです。<strong>URIにも反映されます</strong>。V(ヴュー):<strong>monitor</strong>はまだここでは作成してませんが、<strong>アクション名</strong>でもあり、コントローラに実装する<strong>メソッド名</strong>でもあり、Viewとしての<strong>rhtmlファイル名</strong>であったりします。この命名規則がしっかりしたところが、Railsが優れた生産性を誇る仕組みでもあります。この恩恵は非常に効率的ですね。MVCに着眼すれば、これからの作業の太枠が決まります。</p>
<div align="left">
<ul><li> コントローラのスタブメソッド作成</li>
<li>ヴューの作成</li>
<li>URLの決定</li>
</ul><p>まずアクセス先のURLを決めてしまいます。</p>
</div>
<p align="left"><a href="http://192.168.1.29:3008/hacks/monitor">http://192.168.1.29:3008/hacks/monitor</a></p>
<p align="left">にすることにして、</p>
<p align="left">
コントローラのスタブメソッド作成します。(<a>file:///C:/InstantRails/rails_apps/hacks/app/controllers/hacks_controller.rb</a>)</p>
<blockquote>
<p align="left">class HacksController < ApplicationController<br />
def index<br />
#<br />
# URI省略時のインデックスページの処理。特定のアクションにたらい回します。<br />
#<br />
monitor<br />
render :action => 'monitor'<br />
end<br />
def monitor<br />
#<br />
# ここに処理を書きます。アクセス時の業務処理です。<br />
#<br />
end<br />
def tmp<br />
#<br />
# ここに処理を書きます。まだメソッド名も決めてませんが「送信ボタン」に対応するアクションです。<br />
#<br />
end<br />
end</p>
</blockquote>
<p align="left"> </p>
<p align="left"><strong>ヴューの作成</strong></p>
<p align="left">レイアウトをまず決めます。対応するコントローラに対して1本作成します。</p>
<p align="left">
<a>file:///C:/InstantRails/rails_apps/hacks/app/views/layouts/hacks.rhtml</a></p>
<p align="left">
これは、外枠だけの入れ物なので、既存のレイアウトをそのまま複製してしまいます。タイトルくらいはそれらしく編集しておきましょう。</p>
<blockquote>
<p align="left"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN"<br />
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br /><br />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><br />
<head><br />
<meta http-equiv="content-type" content="text/html;charset=UTF-8"
/><br />
<%= javascript_include_tag :defaults %><br />
<%= stylesheet_link_tag 'scaffold' %><br />
<title>Ajax呼び出し時の内部状態<%= controller.action_name
%></title><br />
</head><br />
<body><br /><br />
<p style="color: green"><%= flash[:notice] %></p><br /><br />
<%= yield %><br /><br />
</body><br />
</html></p>
</blockquote>
<p align="left">yieldに入るアクションごとの部品ヴューは</p>
<p align="left">
<a>file:///C:/InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml</a></p>
<p align="left">になるでしょう。</p>
<p align="left">内容は、</p>
<blockquote>
<p align="left"><h1>Monitor</h1><br /><br />
<% form_tag :action => 'tmp' do %><br />
<%= render :partial => 'form' %><br />
<%= submit_tag '送信' %><br />
<% end %></p>
</blockquote>
<p align="left">
な感じにしておきます。送信ボタン押下時のメソッド名をそろそろ決めておかないといけませんが、とりあえず、こうしておきます。</p>
<p align="left"> 画面自体は出ることをサーバにて確認できます。</p>
<p align="left">
では、ここからいよいよメインディッシュにんります。RailsでAjaxを使うには、対応するいくつかのメソッドが用意されています。<strong>XMLHttpRequest</strong>では「<strong>form_tag</strong>」は使用しないのです。その代わりに「<font color="#000000"><strong>form_remote_tag
メソッド</strong></font>」を使用します。</p>
<p align="left"><font style="background-color:rgb(0,255,0);" color="#0000FF"><strong>form_remote_tag メソッド</strong></font></p>
<p align="left"><strong>XMLHttpRequest</strong>の機能を活用するためのメソッドです。</p>
<p align="left">基本構造は、</p>
<blockquote>
<p align="left"><%=<strong>form_remote_tag</strong>(...<strong><font color="#0000FF"><em>param</em></font></strong>...) %><br />
<div></div><br />
<p><br />
<%= submit_tag '送信' %><br />
</p><br />
<%=<strong>end_form_tag</strong>%></p>
</blockquote>
<p align="left"> パラメータ部分は多少複雑です。ハッシュ形式の指定方法です。</p>
<p align="left">それぞれのキー項目をみていきます。<font color="#FF0000">赤字</font>は必須指定。</p>
<div align="left">
<ul><li><font color="#FF0000"><strong>:update => ""</strong></font></li>
<li><font color="#FF0000"><strong>:url => {}</strong></font></li>
<li>:position => ""</li>
<li>:success => ""</li>
<li>:loading => ""</li>
<li>:loaded => ""</li>
<li>:interactive => ""</li>
<li>:failure => ""</li>
</ul></div>
<p align="left">:update => "表示要素のid属性値"</p>
<p align="left">
なんだけれどもここは結構重要です。肝です。<strong>:complete</strong>や<strong>:success</strong>指定との違いがわかりづらいのです。<a href="http://d.hatena.ne.jp/sakusan_net/20080417/1208399227">ここに参考にできる記事</a>がありますが、もっと調べておく必要性を感じます。</p>
<p align="left"> </p>
<p align="left">:url => { :action => リクエストを処理するアクションのシンボル }</p>
<p align="left">:position => "挿入位置"</p>
<p align="left">:success => "XMLHttpRequestのreadystateが成功時"</p>
<p align="left">ちなみに、readystateがsuccess
というのは厳密にはないはずなのだが、指定できるそうだ。completeとほとんど似た状態だが、わずかに:successのほうが早い状態になります。</p>
<p align="left">:complete => "Element.toggle('id属性値')"</p>
<p align="center"><strong>readystate</strong></p>
<table cellspacing="1" cellpadding="1" width="200" align="center" border="1"><tbody><tr><td> </td>
<td>状態</td>
<td>意味</td>
</tr><tr><td>0</td>
<td>uninitialized</td>
<td>初期化されていない</td>
</tr><tr><td>1</td>
<td>loading</td>
<td>読み込み中</td>
</tr><tr><td>2</td>
<td>loaded</td>
<td>読み込み完了</td>
</tr><tr><td>3</td>
<td>interactive</td>
<td>操作可能</td>
</tr><tr><td>4</td>
<td>complete</td>
<td>準備完了</td>
</tr></tbody></table><p align="center"> </p>
<p align="left">
<a>file:///C:/InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml</a></p>
<blockquote>
<p align="left"> <strong><%= form_remote_tag (</strong><br /><font color="#FF0000"> :update => "complete",<br />
:url => { :action => :zero_update },</font><br />
:position => "top",<br />
:success => "$('success').innerHTML='成功; ステータスコード='+request.status",<br />
:loading => "$('loading').innerHTML='リクエスト送信中…;
ステータスコード='+request.status",<br />
:loaded => "$('loaded').innerHTML='リクエスト送信完了;
ステータスコード='+request.status",<br />
:interactive => "$('inter').innerHTML='レスポンス受信中;
ステータスコード='+request.status",<br />
:failure => "$('failure').innerHTML='エラー;
ステータスコード='+request.status"<strong>) %></strong><br />
<h3>Ajax呼び出しの内部状態を表示します</h3><br />
<div id="loading" style="font-size: 1.2em"></div><br />
<div id="loaded" style="font-size: 1.2em"></div><br />
<div id="inter" style="font-size: 1.2em"></div><br />
<div id="success" style="font-size: 1.2em; color:
green"></div><br />
<div id="failure" style="font-size: 1.2em; color: red"></div><br />
<div id="complete" style="font-size: 1.2em; color:
green"></div><br />
<p><br />
<%=<strong>submit_tag</strong>'送信' %><br />
</p><strong><br />
<%=</strong><strong>end_form_tag %></strong></p>
</blockquote>
<p align="left">
<a>file:///C:/InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml</a></p>
<blockquote>
<p align="left"> def<font color="#FF0000"><strong>zero_update</strong></font><br />
#<br />
# ここに処理を書きます。まだメソッド名も決めてませんが「送信ボタン」に対応するアクションです。<br />
#<br />
<strong>render :text => "Ajax hello!!!"</strong><br />
end</p>
</blockquote>
<p align="left"><strong>render :text => "Ajax hello!!!"</strong></p>
<p align="left">
ここが遷移しない仕組みです。遷移先の画面指定などはしていないのです。この例ではサーバ側の固定文字列を返していますが、コントローラで料理ができるということは、「可変データを非同期に返せる」ということです。静的なサーバ上のデータを返したいだけであるならば、もっと別の手法があります。その手法は別のテーマで触れる予定です。</p>
<p align="left">変換後のHTMLは</p>
<blockquote>
<p align="left"> <form action="/hacks/zero_update"
method="post"<strong>onsubmit</strong>="<font color="#0000FF"><strong>new
Ajax.Updater(</strong></font>'<font color="#003366"><strong>complete</strong></font>', '<strong><font color="#FF0000">/hacks/zero_update</font></strong>', {asynchronous:true,
evalScripts:true, insertion:Insertion.Top,
onFailure:function(request){$('failure').innerHTML='エラー;
ステータスコード='+request.status},
onInteractive:function(request){$('inter').innerHTML='レスポンス受信中;
ステータスコード='+request.status},
onLoaded:function(request){$('loaded').innerHTML='リクエスト送信完了;
ステータスコード='+request.status},
onLoading:function(request){$('loading').innerHTML='リクエスト送信中…;
ステータスコード='+request.status},
onSuccess:function(request){$('success').innerHTML='成功;
ステータスコード='+request.status}, parameters:Form.serialize(this)}<font color="#0000FF"><strong>); return false;</strong></font>"><br />
<h3>Ajax呼び出しの内部状態を表示します</h3><br /><br />
<div id="<strong><font color="#008080">loading</font></strong>"
style="font-size: 1.2em"></div><br />
<div id="<strong><font color="#008080">loaded</font></strong>"
style="font-size: 1.2em"></div><br />
<div id="<strong><font color="#008080">inter</font></strong>"
style="font-size: 1.2em"></div><br />
<div id="<strong><font color="#008080">success</font></strong>"
style="font-size: 1.2em; color: green"></div><br />
<div id="<strong><font color="#008080">failure</font></strong>"
style="font-size: 1.2em; color: red"></div><br />
<div id="<font color="#003366"><strong>complete</strong></font>"
style="font-size: 1.2em; color: green"></div><br />
<p><br />
<input name="commit" type="submit" value="送信" /><br />
</p><br /><br />
</form></p>
</blockquote>
<p align="left"> 内部では、<strong>prototype.js</strong>のクラスが使用されているようです。</p>
<p align="left">
しかも変換されているのは、「<strong>Ajax.Request</strong>」ではなく「<strong>Ajax.Updater</strong>」のようです。ほとんど似た処理ですが、サーバ上のデータをページに非同期に挿入するのに使います。</p>
<p align="left">
非同期の持ち味を実感するには、クライアントサイドで「onSubmit」とか「onClick」とかでは、実感が薄いですね。</p>
<p align="left">トリガーとなるイベントの種類や指定方法も整理しておくといいでしょう。</p>
<p align="left">
その前に、<strong>:successと:completeの違いについて</strong>整理しておきます。上記のソースの実行結果は、実は問題があります。</p>
<p align="left"><strong>:successと</strong><strong>:completeの違いについて</strong></p>
<p align="left">
どちらもサーバからレスポンスが返される準備が整った状態ではありますが、ステータスでいうと、まず<strong>:successになり、次に:completeになります。</strong>これを同じ意味と捕らえるのはもったいないことです。実際に<strong>:update</strong>で指定された要素に結果が挿入されるのは、<strong>:completeのタイミングですが、そもそも非同期処理のため、ページが遷移せず、</strong><strong>つまりは<font color="#FF0000">既読のデータ(id=completeで指定された領域のデータ</font></strong><strong><font color="#FF0000">)は消えないのです</font>。</strong>そのため、前回サーバより取得した値は消えずに残り、そこに追記という形で対象要素にロードされるため、意図した結果にならないでしょう。その場合に、<strong>:successのステータスにおいて対象要素の「過去の値」を消す</strong>処理を施すことができます。</p>
<blockquote>
<p align="left"> <%= form_remote_tag (<br />
:update => "complete",<br />
:url => { :action => :zero_update },<br />
:position => "top",<br />
<font color="#FF0000"><strong>:success
=></strong><strong>"$('complete').innerHTML='';</strong></font>$('success').innerHTML='成功;
ステータスコード='+request.status",<br />
:loading => "$('loading').innerHTML='リクエスト送信中…;
ステータスコード='+request.status",<br />
:loaded => "$('loaded').innerHTML='リクエスト送信完了;
ステータスコード='+request.status",<br />
:interactive => "$('inter').innerHTML='レスポンス受信中;
ステータスコード='+request.status",<br />
:failure => "$('failure').innerHTML='エラー; ステータスコード='+request.status")
%><br />
<h3>Ajax呼び出しの内部状態を表示します</h3><br />
<div id="loading" style="font-size: 1.2em"></div><br />
<div id="loaded" style="font-size: 1.2em"></div><br />
<div id="inter" style="font-size: 1.2em"></div><br />
<div id="success" style="font-size: 1.2em; color:
green"></div><br />
<div id="failure" style="font-size: 1.2em; color: red"></div><br />
<div id="complete" style="font-size: 1.2em; color:
green"></div><br />
<p><br />
<%= submit_tag '送信' %><br />
</p><br />
<%= end_form_tag %></p>
</blockquote>
<p align="left"> </p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">遷移させないということは</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">RailsでのAjax利用の構造</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">自作のJavaScriptはどこに書くのか?</font></h2>
<p align="center"><a href="#myjavascript">link</a></p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">サーバ内テンプレートを元にコンボボックス表示</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">リクエストの判別方法</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">DBの値を元にコンボボックス表示</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">定期的なリクエスト実行</font></h2>
<p align="left">定期的な実行を伴うAjaxの処理は、「<strong><font color="#0000FF">PeriodicalExecuter</font></strong>」を使用しますが、Railsではこれをさらにラップして「<strong><font color="#0000FF">periodically_call_remote</font></strong>」というメソッドを使用します。</p>
<p align="left">
ここでは、サンプルとして、クライアント側から非同期に、ブラウザを利用しているユーザからは意識させずに、サーバーにアクセスし、サーバ上にあるDBの最新情報を取得して、それを画面を遷移させることなく表示するサンプルを作成してみます。</p>
<p align="left">対象の画面:index3</p>
<p align="left">イベント:タイマー</p>
<p align="left">定期実行時間:3秒</p>
<p align="left">リクエスト先のコントローラ:greeting</p>
<p align="left">リクエスト先のアクション:select_todos_by_mysql</p>
<p align="left">レスポンス先のエレメントID:complete</p>
<p align="left">とすると、</p>
<p align="left">1、Viewは(greeting/index3.html.erb)</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"> <hr/><%=<strong><font color="#0000FF">periodically_call_remote</font></strong>(:update =>
"<strong>complete</strong>", :frequency =><strong>3</strong>,<br />
:url => {:action => :<strong>select_todos_by_mysql</strong>},<br />
:position => "top",<br />
:success => "$('complete').innerHTML = ''",<br />
:loading => "",<br />
:loaded => "",<br />
:interactive => "",<br />
:failure => "") %><br />
<div id="success" style="font-size: 1.0em; color: green"><br />
</div><br />
<div id="<strong>complete</strong>" style="font-size: 1.0em; color:
green"></div></p>
</blockquote>
<p align="left">2、コントローラは(greeting_controller.rb)</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"> def<strong><font color="#0000FF">select_todos_by_mysql</font></strong></p>
<p align="left"> if request.xml_http_request?()<br />
@stmt = @con.createStatement<br />
rs = @stmt.executeQuery("select * from todos")<br />
str = ''<br />
while rs.next<br />
str += rs.getString(3)<br />
str += "<br />"<br />
end<br />
puts str<br />
<strong><font color="#0000FF">render :text =>
str<br /></font></strong> end</p>
<p align="left"> end</p>
</blockquote>
<p align="left">になります。(ここでDB接続と切断は他のアクションでも共通処理になるはずなので外だしすることにします。※後述します。)</p>
<p align="left">機能の内容をみてみましょう。</p>
<p align="left"> <strong><font style="background-color:#00ff00;" color="#0000FF">periodically_call_remoteメソッド</font></strong></p>
<ul><li>
<div align="left">:update => レスポンス先のエレメントID指定,</div>
</li>
<li>
<div align="left">:frequency => 秒数,</div>
</li>
<li>
<div align="left">:url => {:action => :アクション名(:メソッド名)},</div>
</li>
<li>
<div align="left">:position => 挿入場所,</div>
</li>
<li>
<div align="left">:success => レスポンス完了前の直前処理,</div>
</li>
</ul><p align="left">変換後のHTMLは</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><script type="text/javascript"><br />
//<![CDATA[<br />
new PeriodicalExecuter(function() {new Ajax.Updater('complete',
'/greeting/select_todos_by_mysql', {asynchronous:true, evalScripts:true,
insertion:Insertion.Top, onFailure:function(request){},
onInteractive:function(request){}, onLoaded:function(request){},
onLoading:function(request){},
onSuccess:function(request){$('complete').innerHTML = ''},
parameters:'authenticity_token=' +
encodeURIComponent('e4a2e3f8ab38073ed2a9d8acaced418f8042a651')})}, 1)<br />
//]]><br /><br />
</script><br />
<div id="success" style="font-size: 1.0em; color: green"></div><br />
<div id="complete" style="font-size: 1.0em; color:
green"></div></p>
</blockquote>
<p align="left">あ</p>
<p align="left"> </p>
<p align="left"> </p>
<p align="center"> </p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">リクエスト情報</font></h2>
<p align="center">a</p>
<hr /><p> </p>
<p> </p>
<p align="left"><font size="2"><strong>【参考文献】:AJAX HACKS 6章
Hacks45-52(p207~)</strong></font></p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">MVCアーキテクチャ</font></h2>
<p align="left">
MVCとはデザインパターンの一種で、アプリケーションの構成を、Model、View、Controllerというコンポーネントに分けて設計する手法を言う。</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">Ruby On
Rails のインストール</font></h2>
<p align="center">編集中。。。あまりここに時間を割きたくないな。ぼそ</p>
<p align="center">ここでは、InstantRails-1.7-win.zipを導入して使います。</p>
<p align="center"> </p>
<hr /><h2 align="center"><font style="background-color:rgb(204,153,255);" size="6">Rails アプリの作成</font></h2>
<p align="left"><strong><u>1.開発環境</u></strong></p>
<p align="left">始める前に、念のため開発に使用するマシンのスペックを調べておきます。</p>
<p align="left">Windows XP SP2 であれば、まあ問題ないでしょう。今回はWindows2000でやってみます。</p>
<p align="left">ちなみに、マシンスペックの調べ方は、コマンドで「<strong>dxdiag</strong>」</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>dxdiag</strong></font></p>
</blockquote>
<p align="left">今回の開発環境のサンプル)</p>
<p align="left"><font size="1">------------------<br />
System Information<br />
------------------<br />
Time of this report: 10/16/2008, 09:52:20<br />
Machine name: HIDE2000<br />
Operating System: Windows 2000 Professional (5.0, Build 2195) Service Pack
4<br />
Language: Japanese (Regional Setting: Japanese)<br />
System Manufacturer: VMware, Inc.<br />
System Model: VMware Virtual Platform<br />
BIOS: Default System BIOS<br />
Processor: Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz, ~2.4GHz<br />
Memory: 724MB RAM<br />
Page File: 408MB used, 1049MB available<br />
Windows Dir: C:\WINNT<br />
DirectX Version: DirectX 9.0c (4.09.0000.0904)<br />
DX Setup Parameters: Not found<br />
DxDiag Version: 5.03.0001.0904 32bit Unicode</font></p>
<p align="left"><font size="3"><strong>【補足:開発支援の為のIDE Tool】</strong></font></p>
<p align="left"><font size="3">開発支援の為のIDEToolとして、<strong>eclipse</strong>か<strong>Aptana</strong>か<strong>NetBeans</strong>などを利用すると便利だと思います。</font></p>
<p align="left"><font size="3">今回は「<strong>eclipse</strong>」に「<strong>Aptana</strong>」プラグイン、「<strong>RadRails</strong>」プラグインを仕込んで使います。(<a href="#ide_comment01">※</a>)</font></p>
<p align="left"><a class="FCK__AnchorC FCK__AnchorC FCK__AnchorC FCK__AnchorC FCK__AnchorC" id="ide_comment01" name="ide_comment01"><font size="2"><strong>※)</strong></font></a><font size="2"><strong>手っ取り早く環境を構築するには?</strong></font></p>
<p align="left"><font size="2">これらが全部そろった「<strong>pleiades-all-in-one-ultimate_20081006.zip</strong>」がお勧めです。(=>ダウンロードは<a href="http://mergedoc.sourceforge.jp/"><font color="#FF00FF"><strong>こちら</strong></font></a>から。Eclipse
3.4.1
Ganymedeのultimateがお勧めです。ちなみに3.3.1のほうにはultimateでも今回使いたいRadRailsのプラグインが入ってませんでした。。。)</font></p>
<p align="left"><font size="2"><strong>※) eclipse 3.2.1 に
RadRailsプラグインを追加する方法</strong></font></p>
<table style="font-size:10pt;width:500px;" cellspacing="0" cellpadding="0" border="0"><tbody style="font-size:10pt;"><tr style="font-size:10pt;"><td class="bg_01" style="font-size:10pt;background-color:rgb(225,225,225);" align="center"><br class="Apple-interchange-newline" /><img class="dummy" style="border-right:0px;border-top:0px;font-size:10pt;border-left:0px;width:1px;border-bottom:0px;height:1px;" alt="" src="http://www19.atwiki.jp/_fckeditor2.4.2-base_015flash1.css/editor/skin/dummy.gif" /></td>
<td class="bg_02" style="font-size:10pt;background-color:rgb(255,255,255);" valign="middle" align="left">
<div class="padding_s lh_120" style="padding-right:5px;padding-left:5px;font-size:10pt;padding-bottom:5px;line-height:120%;padding-top:5px;">
<p>AptanaプラグインとRailsプラグインのインストール<br style="font-size:10pt;" />
Eclipseを起動し、「ヘルプ」→「ソフトウェアの更新」→「検索してインストール」を選びます。<br style="font-size:10pt;" />
ダイアログボックスが出たら「新規フィーチャーを探す」を選びます。<br style="font-size:10pt;" />
アップデートサイト選択画面で「新規リモート」を選びます。<br style="font-size:10pt;" />
ここでは次の2つのサイトを登録します。<br style="font-size:10pt;" />
・<a style="border-right:0px;border-top:0px;font-size:10pt;border-left:0px;color:rgb(75,158,247);border-bottom:0px;" target="_blank" href="http://update.aptana.com/install/3.2/">http://update.aptana.com/install/3.2/</a><br style="font-size:10pt;" />
・<a style="border-right:0px;border-top:0px;font-size:10pt;border-left:0px;color:rgb(75,158,247);border-bottom:0px;" target="_blank" href="http://update.aptana.com/install/rails/3.2/">http://update.aptana.com/install/rails/3.2/</a><br style="font-size:10pt;" />
1つ目がAptana本体、2つ目がAptanaのRailsプラグインになります。<br style="font-size:10pt;" /><br style="font-size:10pt;" />
リモートサイトを2つ登録し終わったら、「次へ」をクリックし、<br style="font-size:10pt;" />
以降は通常の更新機能と同様に操作して、インストールを行います。<br style="font-size:10pt;" /><br style="font-size:10pt;" />
Railsパースペクティブを開く<br style="font-size:10pt;" />
プラグインのインストールが終わり、Eclipseを再起動したら、<br style="font-size:10pt;" />
Railsパースペクティブを開きます。<br style="font-size:10pt;" />
「ウィンドウ」→「パースペクティブを開く」→「その他」の中に<br style="font-size:10pt;" />
「Rails」というパースペクティブがあるので、これを選択します。</p>
<p>ここを参考にしました。<br style="font-size:10pt;" /><br style="font-size:10pt;" /><a style="border-right:0px;border-top:0px;font-size:10pt;border-left:0px;color:rgb(75,158,247);border-bottom:0px;" target="_blank" href="http://blog.codezine.jp/editor/2007/06/aptana_eclipseruby_on_rails_1.php">http://blog.codezine.jp/editor/2007/06/aptana_eclipseruby_on_rails_1.php</a><br style="font-size:10pt;" /><br style="font-size:10pt;" /><font color="#FF0000">ちなみに、3.3.x だとうまくいきません。</font>3.3用のURLもどこかにあると思いますが、</p>
<p>それは調べていません。</p>
</div>
</td>
</tr></tbody></table><p align="left"><strong><u>2.Railsのヴァージョン</u></strong></p>
<p align="left">Railsの開発の場合、特にヴァージョンの組み合わせは重要です。</p>
<p align="left">
今回は、<strong>InstantRails-1.7-win.zip</strong>をインストールして準備した環境なので、「<strong>Rails
1.2.3</strong>」になります。このヴァージョンが現在最も情報量が豊富です。(=>ダウンロードは<a href="http://rubyforge.org/frs/?group_id=904"><font color="#FF00FF"><strong>こちら</strong></font></a>から。)</p>
<p align="left"><font size="2">※ <strong>ruby</strong>の最新の1.9などは1.8.6に比べてだいぶ変わったようですし、フレームワークである<strong>rails</strong>もヴァージョンが<strong>1.2.X系</strong>と<strong>2.X系</strong>では<strong>scaffold</strong>などかなりやり方が異なります。パッケージ管理Toolである<strong>gem</strong>なども実は<strong>gem</strong>自体のヴァージョンによりインポートできるモジュールのヴァージョンが違ったりと、手抜かりがあるとなかなか手こずりますので注意しましょう。</font></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>ruby
-v<br /></strong></font>ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]</p>
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>gem
env<br /></strong></font>RubyGems Environment:<br />
- VERSION: 0.9.2 (0.9.2)<br />
- INSTALLATION DIRECTORY: C:/InstantRails/ruby/lib/ruby/gems/1.8<br />
- GEM PATH:<br />
- C:/InstantRails/ruby/lib/ruby/gems/1.8<br />
- REMOTE SOURCES:<br />
-<a href="http://gems.rubyforge.org">http://gems.rubyforge.org</a></p>
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>rake
--version</strong></font><br />
rake, version 0.7.2</p>
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>rails
--version</strong></font><br />
Rails 1.2.3</p>
<p align="left"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>mysql
--version</strong></font><br />
mysql Ver 14.12 Distrib 5.0.27, for Win32 (ia32)</p>
</blockquote>
<p align="left"> </p>
<p align="left">・ <strong>もうひとつのヴァージョンの調べ方</strong></p>
<p align="left">
ひとつひとつのコマンドを打ち込んでヴァージョンを調べてもいいけれども、Railsの場合たくさんのパッケージやモジュールで構成されていて調べるのはいささか面倒です。そこで一発でこれらを調べるコマンドを紹介します。ただし、これはプロジェクト内部の<strong>aboutコマンド</strong>なので、少なくとも後述するプロジェクトを何かひとつ作成してから、実行してください。</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><span class="Apple-style-span" style="word-spacing:0px;font:13px/15px 'ms pgothic';text-transform:none;color:rgb(51,51,51);text-indent:0px;letter-spacing:normal;border-collapse:separate;">
<font style="background-color:rgb(192,192,192);" face="Arial" color="#000000"><font size="2">// <font color="#FF0000">これはうまくいきません。</font></font></font></span></p>
<p align="left"><span class="Apple-style-span" style="word-spacing:0px;font:13px/15px 'ms pgothic';text-transform:none;color:rgb(51,51,51);text-indent:0px;letter-spacing:normal;border-collapse:separate;">
<font style="background-color:rgb(192,192,192);"><font size="2"><font face="Arial" color="#000000">C:\InstantRails\rails_apps></font><strong>ruby
script/about</strong></font></font></span></p>
<p align="left"><span class="Apple-style-span" style="word-spacing:0px;font:13px/15px 'ms pgothic';text-transform:none;color:rgb(51,51,51);text-indent:0px;letter-spacing:normal;border-collapse:separate;">
<font size="3"><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks<strong>>ruby
script/about<br /></strong></font>About your application's environment<br /><strong>Ruby version 1.8.6 (i386-mswin32)<br />
RubyGems version 0.9.2<br />
Rails version 1.2.3</strong><br />
Active Record version 1.15.3<br />
Action Pack version 1.13.3<br />
Action Web Service version 1.2.3<br />
Action Mailer version 1.3.3<br />
Active Support version 1.4.2<br />
Application root C:/InstantRails/rails_apps/hacks<br />
Environment development<br />
Database adapter mysql</font></span></p>
</blockquote>
<p align="left"> </p>
<p align="left"><strong><u>3.作成手順</u></strong></p>
<p align="left">
RailsアプリはDB利用を前提としたWebアプリになるため、Railsの命名規則が重要になってきます。ここら辺は<strong><a href="http://www19.atwiki.jp/hide1227/pages/17.html#DRY">DRY</a></strong>や<strong><a href="http://www19.atwiki.jp/hide1227/pages/17.html#CoC">CoC</a></strong>の思想によるところですが、今回のAjax用のRailsアプリサンプルとして以下の情報をまず収集します。</p>
<ul><li>
<div align="left">プロジェクト名:プロジェクトのルートとなる名前、主にフォルダ管理のため。</div>
</li>
<li>
<div align="left">使用するRDB:MySQL,SQLite3,PostgreSQL,SQL Server,DB2,Oracle</div>
</li>
<li>
<div align="left">DB名:<strong>開発用</strong>、テスト用、リリース用の三種類を用意します。</div>
</li>
<li>
<div align="left">テーブル名:<strong>複数形</strong>小文字英数字</div>
</li>
<li>
<div align="left">モデル名:原則としてテーブル名と関連します。<strong>単数形</strong>のテーブル名</div>
</li>
</ul><p align="left">それでは、今回のAjax用のRailsアプリサンプルの情報を定義していきましょう。</p>
<ul><li>
<div align="left">プロジェクト名:<strong>hacks</strong></div>
</li>
<li>
<div align="left">使用するRDB:<strong>mysql</strong></div>
</li>
<li>
<div align="left">
DB名:<strong>hacks_development,hacks_test,hacks_production</strong></div>
</li>
<li>
<div align="left">テーブル名:<strong>kilowatts</strong></div>
</li>
<li>
<div align="left">モデル名:<strong>Kilowatt</strong></div>
</li>
</ul><p align="left">ここで、一応テーブルの定義も決めておきましょうか。</p>
<p align="left"> </p>
<p align="center"><strong>Kilowattsテーブル定義</strong></p>
<div align="center">
<table cellspacing="1" cellpadding="1" width="200" align="center" border="1"><tbody><tr><td>
<p align="center"> <font size="2">NO</font></p>
</td>
<td>
<p align="center"><font size="2">カラム名 </font></p>
</td>
<td>
<p align="center"><font size="2"> 型</font></p>
</td>
<td>
<p align="center"><font size="2"> NotNull</font></p>
</td>
<td>
<p align="center"><font size="2"> 主キー</font></p>
</td>
</tr><tr><td>
<p align="center"><font size="2"> 1</font></p>
</td>
<td>
<p align="center"><font size="2"> id</font></p>
</td>
<td>
<p align="center"><font size="2">int </font></p>
</td>
<td>
<p align="center"><font size="2">true </font></p>
</td>
<td>
<p align="center"><font size="2">true </font></p>
</td>
</tr><tr><td>
<p align="center"><font size="2"> 2</font></p>
</td>
<td>
<p align="center"><font size="2"> kdate</font></p>
</td>
<td>
<p align="center"><font size="2"> text</font></p>
</td>
<td>
<p align="center"><font size="2"> </font></p>
</td>
<td>
<p align="center"><font size="2"> </font></p>
</td>
</tr><tr><td>
<p align="center"><font size="2"> 3</font></p>
</td>
<td>
<p align="center"><font size="2">kwatts </font></p>
</td>
<td>
<p align="center"><font size="2">int </font></p>
</td>
<td>
<p align="center"><font size="2"> </font></p>
</td>
<td>
<p align="center"><font size="2"> </font></p>
</td>
</tr></tbody></table></div>
<p align="left">DDLファイルを作成するとしたら、以下のようになるかと思います。(<a href="#comment_01">※</a>)</p>
<p align="left">DDL:kilowatts.sql</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left">DROP TABLE IF EXISTS kilowatts;<br />
CREATE TABLE kilowatts (<br />
id MEDIUMINT NOT NULL AUTO_INCREMENT,<br />
kdate TEXT,<br />
kwatts INT,<br />
PRIMARY KEY(id)<br />
);</p>
</blockquote>
<p align="left"><a class="FCK__AnchorC FCK__AnchorC FCK__AnchorC FCK__AnchorC FCK__AnchorC" id="comment_01" name="comment_01"><font size="2">※)</font></a><font size="2">ただし、Railsの作成方法では、このようなDB周りの準備もRailsでサポートされており、具体的には<u><a href="#001_create_kilowatts_2">「<strong>マイグレーション</strong>」という手法を使います</a></u>。ちなみに、この作成方法は<a href="#001_create_kilowatts_2"><font color="#FF0000">Rails
1.2.x 系列とRails 2.x 系列で作成手順が違います</font>。</a>これは追って説明します。</font></p>
<p align="left">【参考】:<a href="http://www.oreilly.co.jp/books/4873113040/"><font color="#FF00FF"><strong>ソースダウンロード</strong></font></a></p>
<p align="left">
ちなみに、このページはUTF8になります。ブラウザで文字化けなどしたらエンコードを変更してみてください。<strong>AjaxHacksSamples.zip</strong>を解凍してサンプルコードを手に入れてください。</p>
<p align="left"><strong>【事前準備】</strong></p>
<p dir="ltr" style="margin-right:0px;" align="left">
InstantRailsでインストールした場合は、<strong>InstantRails.exe
は起動</strong>しておきましょう。起動するとApacheとMySQlが立ち上がります。後ほどRailsからDBを作成したり、テーブルを作成しますが、そのためには今回使用する<strong>MySQLがサービスとして起動</strong>している必要があります。Webサーバは開発モードでは他の(Mongrelサーバ)を使うのでApacheは立ち上げる必要性はないですが、DBの確認作業で、phpMyAdminというToolを使う場合は<strong>Apacheサーバを立ち上げておく</strong>必要があります。</p>
<p dir="ltr" style="margin-right:0px;" align="left">
また、DBにMySQLを使用するのであれば、最初に、<strong>my.ini</strong>ファイルにてDBの文字コード指定をしておきます。以下のソースの<font color="#0000FF">青字部分</font>を追記してください。</p>
<p dir="ltr" style="margin-right:0px;" align="left">
C:\InstantRails\mysql\my.ini</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p dir="ltr" style="margin-right:0px;" align="left">; ----------------------
IMPORTANT ---------------------------;<br />
; ${path} is used to specify Instant Rails installation path. ;<br />
;-------------------------------------------------------------;</p>
<p dir="ltr" style="margin-right:0px;" align="left">[mysqld]<br />
datadir=${path}/mysql/data<br />
basedir=${path}/mysql<br />
bind-address=127.0.0.1<br />
; Uncomment for use on USB key<br />
; skip-innodb<br /><strong><font color="#0000FF">default-character-set=utf8<br />
skip-character-set-client-handshake</font></strong></p>
</blockquote>
<p align="left">ここまで準備すれば、雛形部分の作成は<strong>15分もかからないでしょう</strong>。</p>
<p align="left"><strong>【プロジェクトの作成】</strong></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p dir="ltr" style="margin-right:0px;" align="left">// 1.0
railsアプリのルートフォルダに移動<br />
// InstantRailsでインストールした場合には、その下に「rails_apps」があるはず。そこです。<br /><font style="background-color:rgb(153,204,0);">C:\><strong>cd
C:\InstantRails\rails_apps</strong></font></p>
<p dir="ltr" style="margin-right:0px;" align="left">// 2.0 railsコマンドの実行<br />
// 通常は、Rails 1.2.3 の場合、DBは mysql になります。<br />
// rails hacks<br />
//<br />
// デフォルトじゃないDBシステムを指定するには<br />
// rails hacks -d mysql<br />
// かもしくは、<br />
// rails hacks --database=mysql<br />
//<br /><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps><strong>rails
hacks -d mysql</strong></font></p>
</blockquote>
<p align="left"><strong> 【DB作成】</strong></p>
<p align="left">
<strong>DBの作成の仕方</strong>には幾通りかあります。各ベンダーにより簡単なやりかたがそれぞれあるでしょうが、RailsにはrakeコマンドでDB作成Toolを作成することもできます。それを使用すればマルチDBの作成が夢ではないと思いますが、それは次回のテーマに譲ることにして、ここでは、使用するDBをMySQLとした場合、InstantRails導入した際に利用できる<strong>phpMyAdmin</strong>を使用して簡単に作成してしまいましょう。InstantRails.exeが立ち上がっている状態であれば、以下のURLにアクセスできるはずです。</p>
<p align="left"><a href="http://127.0.0.1/mysql/">http://127.0.0.1/mysql/</a></p>
<p align="left">今回作成するDBは三種類です。</p>
<ul><li>
<div align="left"><strong>hacks_development</strong></div>
</li>
<li>
<div align="left"><strong>hacks_test</strong></div>
</li>
<li>
<div align="left"><strong>hacks_production</strong></div>
</li>
</ul><p align="left">
これは先ほどのプロジェクトの作成の際に自動で命名規約されているDB名です。もちろんこれを変更することも可能ですが、それは以下のリソースに定義してあります。まず素直に自動生成されたソースを覗いてみましょう。</p>
<p align="left">
C:\InstantRails\rails_apps\hacks\config\<strong>database.yml</strong></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left">development:<br />
adapter: mysql<br />
database:<strong>hacks_development</strong><br />
username: root<br />
password:<br />
host: localhost</p>
<p align="left">test:<br />
adapter: mysql<br />
database:<strong>hacks_test</strong><br />
username: root<br />
password:<br />
host: localhost</p>
<p align="left">production:<br />
adapter: mysql<br />
database:<strong>hacks_production</strong><br />
username: root<br />
password:<br />
host: localhost</p>
</blockquote>
<p align="left">
今回はここでデフォルトに指定されているDB名をそのまま使用することにします。DB名を変えたければ、[database:]の値を変えればいいでしょう。</p>
<p align="left">ちなみに、今回はMySQLなのでこのまま使用しますが、<font color="#FF0000">Oracleなどの場合は、DBを複数作成するよりも、スキーマを3つ用意したほうが現実的</font>だと思われます。</p>
<p align="left"><strong>【補足:文字コード問題】</strong></p>
<p align="left">
<strong>my.ini</strong>に指定したように、この<strong>database.yml</strong>ファイルでも文字コードを指定します。3つのDB定義の最後の要素にそれぞれ以下を追加します。(※MySQL使用時には必要ですがOracle使用する場合は必要がないようです。)</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"> <strong>encoding: utf8</strong></p>
</blockquote>
<p align="left">
また、文字コード問題というと、DBの文字コードだけでなく、<strong>Ruby自体の文字コード指定をする必要があります</strong>。<br />
今回のRailsアプリの文字コード指定は、「<strong>environment.rb</strong>」というファイルでの最初の行で設定します。<br /><br />
例)文字コードをUTF-8に指定するやりかた。</p>
<div align="left">
<blockquote><strong>$KCODE = "UTF8"<br /></strong></blockquote>
</div>
<p align="left"><br />
もしくは、</p>
<div align="left">
<blockquote>$KCODE = 'u'<br /></blockquote>
</div>
<p align="left"><br />
どちらも同じ意味です。最初の 1
バイトしか読み取っていないようです。しかも大文字小文字すら関係ないようです。でも自分としては可読性を考慮してUTF8と記述したいところです。<br /><br />
【参考サイト】<br /><a href="http://www.ruby-lang.org/ja/man/html/_C1C8A4DFB9FEA4DFCAD1BFF4.html">http://www.ruby-lang.org/ja/man/html/_C1C8A4DFB9FEA4DFCAD1BFF4.html</a></p>
<p align="left"> </p>
<p align="left">では、phpMyAdminのサイトにてこれらの3つのDBを作成してみましょう。</p>
<p align="left">確認は、phpMyAdminでもできますが、コンソールからDBが作成されたことを確認してみます。</p>
<blockquote>
<p align="left">C:\InstantRails\rails_apps\hacks>mysql -u root<br />
Welcome to the MySQL monitor. Commands end with ; or \g.<br />
Your MySQL connection id is 18 to server version: 5.0.27-community<br /><br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br /><br />
mysql> show databases;<br />
+----------------------------------------+<br />
| Database |<br />
+----------------------------------------+<br />
| information_schema |<br />
|<strong>hacks_development</strong> |<br />
|<strong>hacks_production</strong> |<br />
|<strong>hacks_test</strong> |<br />
+----------------------------------------+<br />
29 rows in set (0.01 sec)<br /><br />
mysql></p>
</blockquote>
<p align="left"> </p>
<p align="left"><strong> 【eclipse へインポート】</strong></p>
<p align="left">この辺で、今後の作業の円滑を図り、eclipseへプロジェクトごとインポートしておきます。</p>
<p align="left"> <img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks002.jpg" /></p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks003.jpg" /></p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks004.jpg" /></p>
<p align="left">プロジェクトを選択</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks005.jpg" /></p>
<p align="left">選択してOK押下</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks006.jpg" /></p>
<p align="left">作成されたことを確認</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks007.jpg" /></p>
<p align="left">プロジェクトをマウントしたら、すかさずeclipseプロジェクト上の文字コードをUTF8に設定する。</p>
<p align="left"> <img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks008.jpg" /></p>
<p align="left"> <img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks009.jpg" /></p>
<p align="center"> </p>
<p align="left"><font size="2"><font size="3"><strong>【テーブルの作成】</strong><br /></font>事前準備してあるテーブル定義書に従い、Rails用のDDLファイルといえる<strong><font style="background-color:rgb(255,255,153);">マイグレーションファイル</font>を作成します</strong>。<br />
作成の手順は、<font color="#FF0000">Rails 1.2.3 と Rails 2.0.2 では微妙に異なります</font>。<br /><br /><strong>Rails 1.2.3</strong>では、<br /></font></p>
<div align="left">
<ol><li><font size="2">ジェネレータの「<strong><font color="#0000FF">migration</font></strong>」サブコマンドにてマイグレーションファイルのスタブを作成して後</font></li>
<li><font size="2">テーブル定義書に従い、マイグレーションファイルの編集</font></li>
<li><font size="2">「<strong>db:migrate</strong>」コマンドを実行する。</font></li>
<li><font size="2">その後、「<strong>scaffold</strong>」を実行し、テーブルに対応するモデルクラスやコントロールクラスのCRUD構成を一気に作成する。</font></li>
</ol></div>
<p align="left"><br /><font size="2">という手順になるが、<strong>Rails 2.0.2</strong>では</font></p>
<div align="left">
<ol><li><font size="2">「<strong>scaffold</strong>」にて、MVCアーキテクチャのすべてのソースを一気に作成する。</font></li>
<li><font size="2">「<strong>db:migrate</strong>」コマンドを実行する。</font></li>
</ol></div>
<p align="left"><br /><font size="2">ただし、その際の<font color="#FF0000">「scaffold」のコマンドオプションの指定の仕方が変わりました。カラム名や型を同時に宣言しなければならなくなりました。</font><br /><br />
ここでは、Railsのヴァージョンは 1.2.3 なので、最初の手続きによるやり方で行う。<br />
ちなみに、eclipse の RadRailsパースペクティブにおいては、generatorというviewが存在し、<br />
そこでコマンドを実行が可能です。<br /><br />
ここでは、コマンドラインでの実行方法を紹介します。(Rails 1.2.3の場合)<br /></font></p>
<div align="left">
<blockquote>
<p><font size="3"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>ruby
script/generate migration create_kilowatts</strong></span><br />
create db/migrate<br />
create db/migrate/<strong><font color="#0000FF">001_create_kilowatts.rb</font></strong><br /><br />
C:\InstantRails\rails_apps\hacks></font></p>
</blockquote>
</div>
<p align="left">ちなみに、Rails
2.0.2の場合は <strong>migration</strong>ではなく、ここでいきなり<strong>scaffold </strong>していいです。</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>ruby
script/generate scaffold kilowatt kdate:text kwatts:integer</strong></span></p>
</blockquote>
<p align="left">では、eclipse に戻って、作業領域をリフレッシュ(F5)した後、編集してみましょう。</p>
<p align="left"><strong><a class="FCK__AnchorC" name="001_create_kilowatts"><font color="#000000" size="3">001_create_kilowatts.rb</font></a>(Rails 1.2.3の場合)</strong></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left">class CreateKilowatts < ActiveRecord::Migration<br />
def self.up<br />
create_table(:kilowatts) do |table|<br /><strong><font color="#0000FF"> table.column :kdate , :text<br />
table.column :kwatts , :integer</font></strong><br />
end<br />
end<br /><br />
def self.down<br />
drop_table :kilowatts<br />
end<br />
end</p>
</blockquote>
<p align="left"><a class="FCK__AnchorC" name="001_create_kilowatts_2"><font color="#000000" size="3"><strong>001_create_kilowatts.rb</strong></font></a><strong>(Rails
2.0.2の場合)</strong></p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left">class CreateKilowatts < ActiveRecord::Migration<br />
def self.up<br />
create_table(:kilowatts) do |table|</p>
<p align="left"><font color="#FF0000"><strong> table.text :kdate<br />
table.integer :kwatts</strong></font> <br />
end<br />
end<br /><br />
def self.down<br />
drop_table :kilowatts<br />
end<br />
end</p>
</blockquote>
<p align="left"><strong><font size="2">(※注意)</font></strong></p>
<p align="left"><font size="2"><font color="#FF0000">Rails1.2.3とRails2.0.2の表記の違いに</font>注意してください。また2.0.2の場合、自動生成される「<strong>table.timestamps</strong>」ですが、これはカラムの「<strong><font color="#000000">create_at</font></strong>」と「<strong><font color="#000000">update_at</font></strong>」に相当します。</font></p>
<p align="left">
このマイグレーションファイルはマルチDBに対応した<strong>Rails独自の文法</strong>による記載になります。</p>
<p align="left">非常に便利なものだが、まず各ベンダーのRDBの型との対応に注意しなければなりません。</p>
<p align="left">手元には、<strong>データ型の対応表</strong>が必要になると思われる。</p>
<div align="center">
<table class="style_table" cellspacing="1" align="center" border="0"><tbody><tr><td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">
型</td>
<td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">
説明</td>
<td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">
MySQL</td>
<td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">SQL
Server</td>
<td class="style_td" style="color:rgb(255,255,255);background-color:rgb(0,0,255);text-align:left;">
Oracle</td>
</tr><tr><td class="style_td" style="text-align:left;"><font color="#FF0000"><strong>id</strong></font></td>
<td class="style_td" style="text-align:left;">プライマリキー</td>
<td class="style_td" style="text-align:left;">int(11)</td>
<td class="style_td" style="text-align:left;">int</td>
<td class="style_td" style="text-align:left;">NUMBER(38)</td>
</tr><tr><td class="style_td" style="text-align:left;">:string</td>
<td class="style_td" style="text-align:left;">文字列</td>
<td class="style_td" style="text-align:left;">varchar(255)</td>
<td class="style_td" style="text-align:left;">varchar(255)</td>
<td class="style_td" style="text-align:left;">VARCHAR(255)</td>
</tr><tr><td class="style_td" style="text-align:left;">:text</td>
<td class="style_td" style="text-align:left;">長い文字列</td>
<td class="style_td" style="text-align:left;">text</td>
<td class="style_td" style="text-align:left;">text</td>
<td class="style_td" style="text-align:left;">CLOB</td>
</tr><tr><td class="style_td" style="text-align:left;">:integer</td>
<td class="style_td" style="text-align:left;">整数</td>
<td class="style_td" style="text-align:left;">int(11)</td>
<td class="style_td" style="text-align:left;">int</td>
<td class="style_td" style="text-align:left;">NUMBER(38)</td>
</tr><tr><td class="style_td" style="text-align:left;">:float</td>
<td class="style_td" style="text-align:left;">浮動少数</td>
<td class="style_td" style="text-align:left;">float</td>
<td class="style_td" style="text-align:left;">real</td>
<td class="style_td" style="text-align:left;">NUMBER</td>
</tr><tr><td class="style_td" style="text-align:left;">:decimal</td>
<td class="style_td" style="text-align:left;">精度の高い小数</td>
<td class="style_td" style="text-align:left;">decimal(10,0)</td>
<td class="style_td" style="text-align:left;">decimal(18,0)</td>
<td class="style_td" style="text-align:left;">NUMBER(38)</td>
</tr><tr><td class="style_td" style="text-align:left;">:datetime</td>
<td class="style_td" style="text-align:left;">日時</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;">:timestamp</td>
<td class="style_td" style="text-align:left;">日時(より細かい)</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;">:time</td>
<td class="style_td" style="text-align:left;">時間</td>
<td class="style_td" style="text-align:left;">time</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;">:date</td>
<td class="style_td" style="text-align:left;">日付</td>
<td class="style_td" style="text-align:left;">date</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;">:binary</td>
<td class="style_td" style="text-align:left;">バイナリデータ</td>
<td class="style_td" style="text-align:left;">blob</td>
<td class="style_td" style="text-align:left;">image</td>
<td class="style_td" style="text-align:left;">BLOB</td>
</tr><tr><td class="style_td" style="text-align:left;">:boolean</td>
<td class="style_td" style="text-align:left;">Boolean型</td>
<td class="style_td" style="text-align:left;">tinyint(1)</td>
<td class="style_td" style="text-align:left;">bit</td>
<td class="style_td" style="text-align:left;">NUMBER(1)</td>
</tr><tr><td class="style_td" style="text-align:left;"><font color="#FF0000"><strong>create_at</strong></font></td>
<td class="style_td" style="text-align:left;">マジックフィールド</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr><tr><td class="style_td" style="text-align:left;"><font color="#FF0000"><strong>update_at</strong></font></td>
<td class="style_td" style="text-align:left;">マジックフィールド</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">datetime</td>
<td class="style_td" style="text-align:left;">DATE</td>
</tr></tbody></table></div>
<p align="center"> </p>
<p align="left">次に「<strong>rake db:migrate</strong>」コマンドを実行する。(ちなみに eclipse の
Rake view からも実行が可能だ。)</p>
<blockquote>
<p align="left"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>rake
db:migrate</strong></span><br />
== CreateKilowatts: migrating
=================================================<br />
-- create_table(:kilowatts)<br />
-> 0.0780s<br />
== CreateKilowatts: migrated (0.0780s)
========================================</p>
</blockquote>
<p align="left"> この時、「<a class="item" href="http://127.0.0.1/mysql/tbl_structure.php?db=hacks_development&table=schema_info&token=ae0c25beaf8dfd210e010a4eab058ced">テーブル:
schema_info</a>」も同時に作成されていることに着目しておこう。これはマイグレーションにおける履歴管理のためのテーブルで、Railsの管理の下、テーブル定義が仕様変更となっても、すぐに反映させたり、また逆に元に戻すことを可能にした仕組みだ。</p>
<p align="left">
この点を踏まえると、Railsを使うならば、マイグレーションなしに勝手にテーブル作成することは好ましくないといえるだろう。</p>
<p align="left"><strong>【テーブル作成の確認】</strong></p>
<blockquote>
<p align="left"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>mysql
-u root</strong></span><br />
Welcome to the MySQL monitor. Commands end with ; or \g.<br />
Your MySQL connection id is 30 to server version: 5.0.27-community<br /><br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br /><br /><span style="background-color:rgb(51,204,204);">mysql><strong>use
hacks_development;</strong></span><br />
Database changed<br /><span style="background-color:rgb(51,204,204);">mysql><strong>show
tables;</strong></span><br />
+-----------------------------+<br />
| Tables_in_hacks_development |<br />
+-----------------------------+<br />
| kilowatts |<br />
|<font color="#0000FF">schema_info</font> |<br />
+-----------------------------+<br />
2 rows in set (0.00 sec)<br /><br />
mysql></p>
</blockquote>
<p align="left"><strong>【足場の作成】</strong></p>
<p align="left">
ここで足場となるMVCアーキテクチャに沿ったソースを自動生成します。そのためのコマンドとして、先ほど紹介した「<strong>scaffold</strong>」というコマンドがあります。</p>
<blockquote>
<p align="left"><span style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>ruby
script/generate scaffold kilowatt</strong></span><br />
exists app/controllers/<br />
exists app/helpers/<br />
create app/views/kilowatts<br />
exists app/views/layouts/<br />
exists test/functional/<br />
dependency model<br />
exists app/models/<br />
exists test/unit/<br />
exists test/fixtures/<br />
create app/models/kilowatt.rb<br />
create test/unit/kilowatt_test.rb<br />
create test/fixtures/kilowatts.yml<br />
create app/views/kilowatts/_form.rhtml<br />
create app/views/kilowatts/list.rhtml<br />
create app/views/kilowatts/show.rhtml<br />
create app/views/kilowatts/new.rhtml<br />
create app/views/kilowatts/edit.rhtml<br />
create app/controllers/kilowatts_controller.rb<br />
create test/functional/kilowatts_controller_test.rb<br />
create app/helpers/kilowatts_helper.rb<br />
create app/views/layouts/kilowatts.rhtml<br />
create public/stylesheets/scaffold.css</p>
</blockquote>
<p align="left"> </p>
<p align="left"> </p>
<p align="left">ここまでで雛形が完成したはずです。</p>
<p align="left"><strong>【動作確認】</strong></p>
<p align="left">
では、早速サーバを起動させてみましょう。WebサーバはRailsでは複数用意されていますが、開発モード時点ではApacheなどは使わないです。(かといって現在あがっているApacheを落とす必要はありません。)簡易サーバとして、<strong>Mongrelサーバ</strong>というものが、ありますので、今回はそれを使用します。</p>
<p align="left">
サーバー起動のやり方は、コマンドラインとeclipseでの起動のさせ方とありますが、ポート番号まで比較的簡単に指定できるeclipse起動のやり方を紹介します。</p>
<p align="left">まず、eclipseにて対象となるプロジェクト(今回の場合は「hacks」)を選択して、Runします。</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks010.jpg" /></p>
<p align="left"> <img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks011.jpg" /></p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks012.jpg" /></p>
<p align="left">
ここでOKを押下すれば、対象のサーバインスタンスが立ち上がるはずなのですが、実際には別のインスタンスが起動してしまうような現象に遭遇しました。ヴァージョンは、3.2.1でも3.4.1でも起こります。なのでその場合は、一旦関係のないサーバインスタンスを停止し、再度Serversヴューにて起動対象のサーバインスタンスを選択して実行してみてください。</p>
<p align="left"><img alt="" src="http://www19.atwiki.jp/hide1227/?cmd=upload&act=open&page=Ruby%20OnRails%20%E3%81%A8%20Ajax&file=rail_hacks013.jpg" /></p>
<p align="left">以上のように起動すれば、Webアプリが起動されているはずです。</p>
<p align="left">以下のURLをブラウザで指定してみましょう。</p>
<p align="left">(今回はIP指定しますが、普段の開発ではHOSTはlocalhostか127.0.0.1でかまわないでしょう。)</p>
<p align="left">// 今回のURL<br /><a href="http://192.168.1.29:3008/kilowatts/">http://192.168.1.29:3008/kilowatts/</a><br /><br />
// 通常はデフォルト指定のままなので以下のURL<br /><a href="http://localhost:3008/kilowatts/">http://localhost:3008/kilowatts/</a><br /><a href="http://127.0.0.1:3008/kilowatts/">http://127.0.0.1:3008/kilowatts/</a></p>
<p align="left">ホスト名の次に指定するURIの要素がテーブル名になっていることに着目してください。</p>
<p align="left">
また、デフォルトの入り口が、indexになるのですが、実際にはlist画面にリダイレクトされています。ここは、Railsの仕組みをもう少し追いかけていくことで判明します。</p>
<p align="left"> </p>
<p align="left">とりあえず、ここまでで Railsのアプリの土台部分がが作成できました。</p>
<p align="left"> </p>
<p align="left">おめでとうございます!!</p>
<p> </p>
<hr /><h2 align="center"><font style="background-color:rgb(204,153,255);" size="6">Ajaxライブラリの導入方法</font></h2>
<p align="left">
Ajaxには多数のライブラリが存在しており、現在では生で「<strong>XMLHttpRequest</strong>」オブジェクトを操作することはあまり機会がなくなっているといえるんではないでしょうか。最も有名なライブラリは「<strong>Prototype</strong>」ですが、これはどうやら<strong>Ruby
On Railsがそのルーツ</strong>だそうです。ということで Railsをやるならデフォルトでついてきてます。</p>
<blockquote>
<p align="left"><strong><%= javascript_include_tag<font color="#0000FF">:defaults</font>%></strong></p>
</blockquote>
<p align="left"> この記述でHTMLソースにはどのように変換されているか調べてみると、</p>
<blockquote>
<p align="left"><script
src="/javascripts/<strong>prototype.js</strong>?1224125580"
type="text/javascript"></script><br />
<script src="/javascripts/<strong>effects.js</strong>?1224125580"
type="text/javascript"></script><br />
<script src="/javascripts/<strong>dragdrop.js</strong>?1224125580"
type="text/javascript"></script><br />
<script src="/javascripts/<strong>controls.js</strong>?1224125580"
type="text/javascript"></script><br />
<script src="/javascripts/<strong>application.js</strong>?1224125580"
type="text/javascript"></script></p>
</blockquote>
<p align="left"> でした。</p>
<p align="left">自動生成された
javascriptライブラリをこの一行でロードしています。一番お手軽な書式ですが、必要なものだけを指定したほうが効率がいいでしょう。その場合は、</p>
<blockquote>
<p align="left"><strong><%= javascript_include_tag<font color="#0000FF">"prototype.js"</font>%></strong></p>
</blockquote>
<p align="left">ところで<font color="#FF0000">、このロードの順番は重要です</font>。前後を入れ替えないこと。</p>
<p align="left">逆に言うと、<a class="FCK__AnchorC" id="myjavascript" name="myjavascript"><font color="#FF0000"><strong>自分で定義した
javascript関数</strong></font>は一番最後にロードされる「<strong>application.js</strong>」に入れるべきです。</a></p>
<p align="left"> </p>
<h2 align="center"><font style="background-color:rgb(204,153,255);" size="6">XMLHttpRequestの使い方</font></h2>
<p align="left">XMLHttpRequestの使い方を調べるためにサンプルを作成しましょう。<br />
Railsでは<strong><font color="#FF0000">XMLHttpRequestを生で使わない</font></strong>とはどういうことでしょうか?</p>
<p align="left">
ひとつには、ライブラリ「<strong>prototype.js</strong>」を内部で利用しているため、そのラッパークラスを通じて操作できるためです。</p>
<p align="left">しかし、Railsの場合は、さらにそれをラッピングしたメソッドが存在し、それを利用することができます。<br /><br />
まず、それを確かめるためのコントロールとヴューを作成したいと思います。<br />
ここで、今回はDBを使わないので、あえてscaffoldはせずに、generateではコントローラだけを指定してモデルは作成しないことにします。必要なのはアクションとその画面のみ…ということで、このようなコマンドを実行してみます。<br /><br />
C(コントローラ):<strong>hacks</strong><br />
V(ヴュー):<strong>monitor</strong></p>
<div align="left">
<blockquote><font style="background-color:rgb(153,204,0);">C:\InstantRails\rails_apps\hacks><strong>ruby
script/generate controller hacks</strong><br /></font> exists
app/controllers/<br />
exists app/helpers/<br />
create app/views/hacks<br />
exists test/functional/<br />
create app/controllers/hacks_controller.rb<br />
create test/functional/hacks_controller_test.rb<br />
create app/helpers/hacks_helper.rb<br /></blockquote>
</div>
<p align="left">
コントローラですが、hacks_controller.rb はJavaでいえばサーブレットみたいなものです。<strong>URIにも反映されます</strong>。V(ヴュー):<strong>monitor</strong>はまだここでは作成してませんが、<strong>アクション名</strong>でもあり、コントローラに実装する<strong>メソッド名</strong>でもあり、Viewとしての<strong>rhtmlファイル名</strong>であったりします。この命名規則がしっかりしたところが、Railsが優れた生産性を誇る仕組みでもあります。この恩恵は非常に効率的ですね。MVCに着眼すれば、これからの作業の太枠が決まります。</p>
<div align="left">
<ul><li> コントローラのスタブメソッド作成</li>
<li>ヴューの作成</li>
<li>URLの決定</li>
</ul><p>まずアクセス先のURLを決めてしまいます。</p>
</div>
<p align="left"><a href="http://192.168.1.29:3008/hacks/monitor">http://192.168.1.29:3008/hacks/monitor</a></p>
<p align="left">にすることにして、</p>
<p align="left">
コントローラのスタブメソッド作成します。(<a>file:///C:/InstantRails/rails_apps/hacks/app/controllers/hacks_controller.rb</a>)</p>
<blockquote>
<p align="left">class HacksController < ApplicationController<br />
def index<br />
#<br />
# URI省略時のインデックスページの処理。特定のアクションにたらい回します。<br />
#<br />
monitor<br />
render :action => 'monitor'<br />
end<br />
def monitor<br />
#<br />
# ここに処理を書きます。アクセス時の業務処理です。<br />
#<br />
end<br />
def tmp<br />
#<br />
# ここに処理を書きます。まだメソッド名も決めてませんが「送信ボタン」に対応するアクションです。<br />
#<br />
end<br />
end</p>
</blockquote>
<p align="left"> </p>
<p align="left"><strong>ヴューの作成</strong></p>
<p align="left">レイアウトをまず決めます。対応するコントローラに対して1本作成します。</p>
<p align="left">
<a>file:///C:/InstantRails/rails_apps/hacks/app/views/layouts/hacks.rhtml</a></p>
<p align="left">
これは、外枠だけの入れ物なので、既存のレイアウトをそのまま複製してしまいます。タイトルくらいはそれらしく編集しておきましょう。</p>
<blockquote>
<p align="left"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN"<br />
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br /><br />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><br />
<head><br />
<meta http-equiv="content-type" content="text/html;charset=UTF-8"
/><br />
<%= javascript_include_tag :defaults %><br />
<%= stylesheet_link_tag 'scaffold' %><br />
<title>Ajax呼び出し時の内部状態<%= controller.action_name
%></title><br />
</head><br />
<body><br /><br />
<p style="color: green"><%= flash[:notice] %></p><br /><br />
<%= yield %><br /><br />
</body><br />
</html></p>
</blockquote>
<p align="left">yieldに入るアクションごとの部品ヴューは</p>
<p align="left">
<a>file:///C:/InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml</a></p>
<p align="left">になるでしょう。</p>
<p align="left">内容は、</p>
<blockquote>
<p align="left"><h1>Monitor</h1><br /><br />
<% form_tag :action => 'tmp' do %><br />
<%= render :partial => 'form' %><br />
<%= submit_tag '送信' %><br />
<% end %></p>
</blockquote>
<p align="left">
な感じにしておきます。送信ボタン押下時のメソッド名をそろそろ決めておかないといけませんが、とりあえず、こうしておきます。</p>
<p align="left"> 画面自体は出ることをサーバにて確認できます。</p>
<p align="left">
では、ここからいよいよメインディッシュにんります。RailsでAjaxを使うには、対応するいくつかのメソッドが用意されています。<strong>XMLHttpRequest</strong>では「<strong>form_tag</strong>」は使用しないのです。その代わりに「<font color="#000000"><strong>form_remote_tag
メソッド</strong></font>」を使用します。</p>
<p align="left"><font style="background-color:rgb(0,255,0);" color="#0000FF"><strong>form_remote_tag メソッド</strong></font></p>
<p align="left"><strong>XMLHttpRequest</strong>の機能を活用するためのメソッドです。</p>
<p align="left">基本構造は、</p>
<blockquote>
<p align="left"><%=<strong>form_remote_tag</strong>(...<strong><font color="#0000FF"><em>param</em></font></strong>...) %><br />
<div></div><br />
<p><br />
<%= submit_tag '送信' %><br />
</p><br />
<%=<strong>end_form_tag</strong>%></p>
</blockquote>
<p align="left"> パラメータ部分は多少複雑です。ハッシュ形式の指定方法です。</p>
<p align="left">それぞれのキー項目をみていきます。<font color="#FF0000">赤字</font>は必須指定。</p>
<div align="left">
<ul><li><font color="#FF0000"><strong>:update => ""</strong></font></li>
<li><font color="#FF0000"><strong>:url => {}</strong></font></li>
<li>:position => ""</li>
<li>:success => ""</li>
<li>:loading => ""</li>
<li>:loaded => ""</li>
<li>:interactive => ""</li>
<li>:failure => ""</li>
</ul></div>
<p align="left">:update => "表示要素のid属性値"</p>
<p align="left">
なんだけれどもここは結構重要です。肝です。<strong>:complete</strong>や<strong>:success</strong>指定との違いがわかりづらいのです。<a href="http://d.hatena.ne.jp/sakusan_net/20080417/1208399227">ここに参考にできる記事</a>がありますが、もっと調べておく必要性を感じます。</p>
<p align="left"> </p>
<p align="left">:url => { :action => リクエストを処理するアクションのシンボル }</p>
<p align="left">:position => "挿入位置"</p>
<p align="left">:success => "XMLHttpRequestのreadystateが成功時"</p>
<p align="left">ちなみに、readystateがsuccess
というのは厳密にはないはずなのだが、指定できるそうだ。completeとほとんど似た状態だが、わずかに:successのほうが早い状態になります。</p>
<p align="left">:complete => "Element.toggle('id属性値')"</p>
<p align="center"><strong>readystate</strong></p>
<table cellspacing="1" cellpadding="1" width="200" align="center" border="1"><tbody><tr><td> </td>
<td>状態</td>
<td>意味</td>
</tr><tr><td>0</td>
<td>uninitialized</td>
<td>初期化されていない</td>
</tr><tr><td>1</td>
<td>loading</td>
<td>読み込み中</td>
</tr><tr><td>2</td>
<td>loaded</td>
<td>読み込み完了</td>
</tr><tr><td>3</td>
<td>interactive</td>
<td>操作可能</td>
</tr><tr><td>4</td>
<td>complete</td>
<td>準備完了</td>
</tr></tbody></table><p align="center"> </p>
<p align="left">
<a>file:///C:/InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml</a></p>
<blockquote>
<p align="left"> <strong><%= form_remote_tag (</strong><br /><font color="#FF0000"> :update => "complete",<br />
:url => { :action => :zero_update },</font><br />
:position => "top",<br />
:success => "$('success').innerHTML='成功; ステータスコード='+request.status",<br />
:loading => "$('loading').innerHTML='リクエスト送信中…;
ステータスコード='+request.status",<br />
:loaded => "$('loaded').innerHTML='リクエスト送信完了;
ステータスコード='+request.status",<br />
:interactive => "$('inter').innerHTML='レスポンス受信中;
ステータスコード='+request.status",<br />
:failure => "$('failure').innerHTML='エラー;
ステータスコード='+request.status"<strong>) %></strong><br />
<h3>Ajax呼び出しの内部状態を表示します</h3><br />
<div id="loading" style="font-size: 1.2em"></div><br />
<div id="loaded" style="font-size: 1.2em"></div><br />
<div id="inter" style="font-size: 1.2em"></div><br />
<div id="success" style="font-size: 1.2em; color:
green"></div><br />
<div id="failure" style="font-size: 1.2em; color: red"></div><br />
<div id="complete" style="font-size: 1.2em; color:
green"></div><br />
<p><br />
<%=<strong>submit_tag</strong>'送信' %><br />
</p><strong><br />
<%=</strong><strong>end_form_tag %></strong></p>
</blockquote>
<p align="left">
<a>file:///C:/InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml</a></p>
<blockquote>
<p align="left"> def<font color="#FF0000"><strong>zero_update</strong></font><br />
#<br />
# ここに処理を書きます。まだメソッド名も決めてませんが「送信ボタン」に対応するアクションです。<br />
#<br />
<strong>render :text => "Ajax hello!!!"</strong><br />
end</p>
</blockquote>
<p align="left"><strong>render :text => "Ajax hello!!!"</strong></p>
<p align="left">
ここが遷移しない仕組みです。遷移先の画面指定などはしていないのです。この例ではサーバ側の固定文字列を返していますが、コントローラで料理ができるということは、「可変データを非同期に返せる」ということです。静的なサーバ上のデータを返したいだけであるならば、もっと別の手法があります。その手法は別のテーマで触れる予定です。</p>
<p align="left">変換後のHTMLは</p>
<blockquote>
<p align="left"> <form action="/hacks/zero_update"
method="post"<strong>onsubmit</strong>="<font color="#0000FF"><strong>new
Ajax.Updater(</strong></font>'<font color="#003366"><strong>complete</strong></font>', '<strong><font color="#FF0000">/hacks/zero_update</font></strong>', {asynchronous:true,
evalScripts:true, insertion:Insertion.Top,
onFailure:function(request){$('failure').innerHTML='エラー;
ステータスコード='+request.status},
onInteractive:function(request){$('inter').innerHTML='レスポンス受信中;
ステータスコード='+request.status},
onLoaded:function(request){$('loaded').innerHTML='リクエスト送信完了;
ステータスコード='+request.status},
onLoading:function(request){$('loading').innerHTML='リクエスト送信中…;
ステータスコード='+request.status},
onSuccess:function(request){$('success').innerHTML='成功;
ステータスコード='+request.status}, parameters:Form.serialize(this)}<font color="#0000FF"><strong>); return false;</strong></font>"><br />
<h3>Ajax呼び出しの内部状態を表示します</h3><br /><br />
<div id="<strong><font color="#008080">loading</font></strong>"
style="font-size: 1.2em"></div><br />
<div id="<strong><font color="#008080">loaded</font></strong>"
style="font-size: 1.2em"></div><br />
<div id="<strong><font color="#008080">inter</font></strong>"
style="font-size: 1.2em"></div><br />
<div id="<strong><font color="#008080">success</font></strong>"
style="font-size: 1.2em; color: green"></div><br />
<div id="<strong><font color="#008080">failure</font></strong>"
style="font-size: 1.2em; color: red"></div><br />
<div id="<font color="#003366"><strong>complete</strong></font>"
style="font-size: 1.2em; color: green"></div><br />
<p><br />
<input name="commit" type="submit" value="送信" /><br />
</p><br /><br />
</form></p>
</blockquote>
<p align="left"> 内部では、<strong>prototype.js</strong>のクラスが使用されているようです。</p>
<p align="left">
しかも変換されているのは、「<strong>Ajax.Request</strong>」ではなく「<strong>Ajax.Updater</strong>」のようです。ほとんど似た処理ですが、サーバ上のデータをページに非同期に挿入するのに使います。</p>
<p align="left">
非同期の持ち味を実感するには、クライアントサイドで「onSubmit」とか「onClick」とかでは、実感が薄いですね。</p>
<p align="left">トリガーとなるイベントの種類や指定方法も整理しておくといいでしょう。</p>
<p align="left">
その前に、<strong>:successと:completeの違いについて</strong>整理しておきます。上記のソースの実行結果は、実は問題があります。</p>
<p align="left"><strong>:successと</strong><strong>:completeの違いについて</strong></p>
<p align="left">
どちらもサーバからレスポンスが返される準備が整った状態ではありますが、ステータスでいうと、まず<strong>:successになり、次に:completeになります。</strong>これを同じ意味と捕らえるのはもったいないことです。実際に<strong>:update</strong>で指定された要素に結果が挿入されるのは、<strong>:completeのタイミングですが、そもそも非同期処理のため、ページが遷移せず、</strong><strong>つまりは<font color="#FF0000">既読のデータ(id=completeで指定された領域のデータ</font></strong><strong><font color="#FF0000">)は消えないのです</font>。</strong>そのため、前回サーバより取得した値は消えずに残り、そこに追記という形で対象要素にロードされるため、意図した結果にならないでしょう。その場合に、<strong>:successのステータスにおいて対象要素の「過去の値」を消す</strong>処理を施すことができます。</p>
<blockquote>
<p align="left"> <%= form_remote_tag (<br />
:update => "complete",<br />
:url => { :action => :zero_update },<br />
:position => "top",<br />
<font color="#FF0000"><strong>:success
=></strong><strong>"$('complete').innerHTML='';</strong></font>$('success').innerHTML='成功;
ステータスコード='+request.status",<br />
:loading => "$('loading').innerHTML='リクエスト送信中…;
ステータスコード='+request.status",<br />
:loaded => "$('loaded').innerHTML='リクエスト送信完了;
ステータスコード='+request.status",<br />
:interactive => "$('inter').innerHTML='レスポンス受信中;
ステータスコード='+request.status",<br />
:failure => "$('failure').innerHTML='エラー; ステータスコード='+request.status")
%><br />
<h3>Ajax呼び出しの内部状態を表示します</h3><br />
<div id="loading" style="font-size: 1.2em"></div><br />
<div id="loaded" style="font-size: 1.2em"></div><br />
<div id="inter" style="font-size: 1.2em"></div><br />
<div id="success" style="font-size: 1.2em; color:
green"></div><br />
<div id="failure" style="font-size: 1.2em; color: red"></div><br />
<div id="complete" style="font-size: 1.2em; color:
green"></div><br />
<p><br />
<%= submit_tag '送信' %><br />
</p><br />
<%= end_form_tag %></p>
</blockquote>
<p align="left"> </p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">遷移させないということは</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">RailsでのAjax利用の構造</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">自作のJavaScriptはどこに書くのか?</font></h2>
<p align="center"><a href="#myjavascript">link</a></p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">サーバ内テンプレートを元にコンボボックス表示</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">リクエストの判別方法</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">DBの値を元にコンボボックス表示</font></h2>
<p align="center">a</p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">定期的なリクエスト実行</font></h2>
<p align="left">定期的な実行を伴うAjaxの処理は、「<strong><font color="#0000FF">PeriodicalExecuter</font></strong>」を使用しますが、Railsではこれをさらにラップして「<strong><font color="#0000FF">periodically_call_remote</font></strong>」というメソッドを使用します。</p>
<p align="left">
ここでは、サンプルとして、クライアント側から非同期に、ブラウザを利用しているユーザからは意識させずに、サーバーにアクセスし、サーバ上にあるDBの最新情報を取得して、それを画面を遷移させることなく表示するサンプルを作成してみます。</p>
<p align="left">対象の画面:index3</p>
<p align="left">イベント:タイマー</p>
<p align="left">定期実行時間:3秒</p>
<p align="left">リクエスト先のコントローラ:greeting</p>
<p align="left">リクエスト先のアクション:select_todos_by_mysql</p>
<p align="left">レスポンス先のエレメントID:complete</p>
<p align="left">とすると、</p>
<p align="left">1、Viewは(greeting/index3.html.erb)</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"> <hr/><%=<strong><font color="#0000FF">periodically_call_remote</font></strong>(:update =>
"<strong>complete</strong>", :frequency =><strong>3</strong>,<br />
:url => {:action => :<strong>select_todos_by_mysql</strong>},<br />
:position => "top",<br />
:success => "$('complete').innerHTML = ''",<br />
:loading => "",<br />
:loaded => "",<br />
:interactive => "",<br />
:failure => "") %><br />
<div id="success" style="font-size: 1.0em; color: green"><br />
</div><br />
<div id="<strong>complete</strong>" style="font-size: 1.0em; color:
green"></div></p>
</blockquote>
<p align="left">2、コントローラは(greeting_controller.rb)</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"> <strong><font color="#0000FF">def </font> <font color="#0000FF">select_todos_by_mysql</font></strong></p>
<p align="left"> if <strong>request.xml_http_request?()</strong><br />
@stmt = @con.createStatement<br />
rs = @stmt.executeQuery("select * from todos")<br />
str = ''<br />
while rs.next<br />
str += rs.getString(3)<br />
str += "<br />"<br />
end<br />
puts str<br />
<strong><font color="#0000FF">render :text =>
str<br /></font></strong> end</p>
<p align="left"> end</p>
</blockquote>
<p align="left">
になります。(ここでDB接続と切断は他のアクションでも共通処理になるはずなので外だしすることにします。※後述します。)ここで、<strong>request.xml_http_request?()</strong>は非同期でリクエストされた時のみ処理するための記述です。</p>
<p align="left">機能の内容をみてみましょう。</p>
<p align="left"> <strong><font style="background-color:#00ff00;" color="#0000FF">periodically_call_remoteメソッド</font></strong></p>
<ul><li>
<div align="left">:update => レスポンス先のエレメントID指定,</div>
</li>
<li>
<div align="left">:frequency => 秒数,</div>
</li>
<li>
<div align="left">:url => {:action => :アクション名(:メソッド名)},</div>
</li>
<li>
<div align="left">:position => 挿入場所,</div>
</li>
<li>
<div align="left">:success => レスポンス完了前の直前処理,</div>
</li>
</ul><p align="left">変換後のHTMLは</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"><script type="text/javascript"><br />
//<![CDATA[<br />
new <strong>PeriodicalExecuter</strong>(function() {new
<strong>Ajax.Updater</strong>(<strong>'complete'</strong>,
<strong>'/greeting/select_todos_by_mysql'</strong>, {asynchronous:true,
evalScripts:true, insertion:Insertion.Top, onFailure:function(request){},
onInteractive:function(request){}, onLoaded:function(request){},
onLoading:function(request){},
onSuccess:function(request){$('complete').innerHTML = ''},
parameters:'authenticity_token=' +
encodeURIComponent('e4a2e3f8ab38073ed2a9d8acaced418f8042a651')})},
<strong>3</strong>)<br />
//]]><br /><br />
</script><br />
<div id="success" style="font-size: 1.0em; color: green"></div><br />
<div id="<strong>complete</strong>" style="font-size: 1.0em; color:
green"></div></p>
</blockquote>
<p align="left">これだけの記述で、<strong>タイマーによる非同期処理</strong>が実現できます。</p>
<p align="left">
なお、DBアクセスの部分は、今回「<strong>ActiveRecordを使わないやりかた</strong>」として、通常の「DriverManagerによる接続」を実装してみました。しかし、これは<strong>JrubyOnRails</strong>による<strong>JDBC接続</strong>となるため、ここでのトピックとしてのテーマとずれますが、実現方法はいたって簡単です。使用するDBの<strong>JDBCドライバ</strong>を使用するRubyの<strong>libフォルダ</strong>に格納し使います。</p>
<p align="left"> DB接続と切断をアクション共通処理としてくくりだしたいので、</p>
<ol><li>
<div align="left">DB接続(共通処理:除外するアクションも指定可能)</div>
</li>
<li>
<div align="left">アクション:DB操作</div>
</li>
<li>
<div align="left">DB切断(共通処理:除外するアクションも指定可能)</div>
</li>
</ol><p align="left">こういう処理の流れが太枠になります。この構成をRailsで行うには、事前処理と事後処理ということで、</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"> # DB接続部分は外だしし、メソッドの前に実行させる。<br />
before_filter :db_connect, :except => [:index,:index2,:index3,:index4]</p>
<p align="left"> # DB切断は外だしし、メソッドの前に実行させる。<br />
after_filter :db_close, :except => [:index,:index2,:index3,:index4]</p>
</blockquote>
<p align="left"> を定義し、</p>
<blockquote dir="ltr" style="margin-right:0px;">
<p align="left"> private</p>
<p align="left"> def db_connect<br />
begin<br />
java.lang.Class.forName('com.mysql.jdbc.Driver').newInstance<br />
@con =
java.sql.DriverManager.getConnection('jdbc:mysql://localhost/JRoR2MySQLTom01_development',
'root', '');</p>
<p align="left"> # rescue => ex<br />
# @message = 'error occureed !!!'<br />
# ensure<br />
# @con.close if @con<br />
end</p>
<p align="left"> end</p>
<p align="left"> def db_close<br />
@con.close if @con<br />
end</p>
</blockquote>
<p align="left">
を実装します。この処理は「除外指定されていないメソッド」である「select_todos_by_mysql」の前後に差し込まれて実行されるため、DBの接続切断処理が自動的に行われる結果となります。</p>
<p align="left"> </p>
<p align="center"> </p>
<h2 align="center"><font style="background-color:rgb(204,153,255);">リクエスト情報</font></h2>
<p align="center">a</p>
<hr /><p> </p>
<p> </p>