Rails 覚え書き

    Ruby on Rails 覚え書き    

 

 

 

 

 


この文書はいかにもチュートリアルの様ですが、なんのことはない、Rails 超初心者の私の備忘録にすぎません。従って内容は、不正確、不明確、冗長であったりします。ウソを書かないように気を付けてはいますが、過度に信頼しないで下さい。
ここでは、――
  • Windows XP に Ruby on Rails (以降、Rails)の開発および実行環境を構築します。
  • 簡単なWEBアプリケーションを構築します。

Rails とは?みたいな文章は、ネット上のもっと相応しい場所で読んだ方がいいと思います。が、簡単に触れておきましょう。
Rails は まつもとゆきひろ さんが作成された国産プログラミング言語『Ruby』をベースに開発されたWEBアプリケーションフレームワークです。Rails は、デンマーク人 David Heinemeier Hansson によって作られました。
Rails の基本哲学は、「同じことを繰り返さない」(DRY:Don't Repeat Yourself)と「規約は設定に勝る」(CoC:Convention over Configuration)です。前者は、まあ、普通ですが、後者はちょっと変わっています。決められた規約に従えば、お決まりのコードは Rails が代わって生成してくれるのです。その実態がどの様なものか、この覚え書きでも片鱗くらいはつかめるでしょう。

インストールするソフト

  1. Instant Rails
  2. Aptana IDE
  3. MySQL Administrator

Instant Rails は、Railsを走らせるためのミドルウェアがパッケージされたもので、これさえあればRailsベースのアプリが動きます。
Aptana IDE は、統合開発環境です。以前は RadRails と呼ばれていた、Eclipse ベースのソフトです。無くても Rails アプリは書けますが、私はコマンドプロンプトにスクリプト命令を打つよりも、こちらが好みです。
私は MySQL データベースの操作に MySQL Administrator を使っています。

では、(1)のインストールから。
http://instantrails.rubyforge.org/wiki/wiki.pl の [Download] ページから、最新の InstantRails を入手します。執筆時点の最新版は、InstantRails-1.7-win.zip でした。
ダウンロードしたら解凍します。解凍先は、例えば『C:\』としましょう。インストーラはありませんので、InstantRails フォルダを適当な場所に配置したら完了です。
デスクトップに、InstantRails.exe のショートカットを作っておくと便利でしょう。 初回起動時に、『フォルダが移動してるけど、設定ファイルのパスを直すかい?』みたいなことを聞かれるので、[OK]を押しましょう。
InstantRailsには、他にセットアップする項目もないので、さっさと次へ行きましょう。

(2)の Aptana IDE は、Eclipse ベースの統合開発環境です。これ自体はRails専用というわけではありません。
http://www.aptana.com/ から、まず Aptana IDE の Windows 版をダウンロードします。次に、Aptana RadRails の Windows 版もダウンロードします。
Aptana IDE もインストーラはありませんので、解凍して得られたフォルダを適当な場所に置けばOKです。
Aptana RadRails は、Windows のインストーラですので実行してインストールします。 まだこれだけでは RadRails は使えません(なぜ?)。
では、Aptana IDE を起動してみましょう。起動時に、作業用ディレクトリを聞かれますので、適当な場所を指示します。
ここから、Aptana RadRails のセットアップです。

Aptana IDE のメニューから、[Help} -> [ソフトウェア更新] -> [検索およびインストール]とたどります。
[インストールする新規フィーチャーを検索]を選び、[次へ]をクリック。
[Ruby on Rails Development Environment]にチェックを付けて、[終了]をクリック。
[Ruby on Rails Development Environment]を選び、指示に従ってセットアップを続けます。
完了のダイアログボックスが表示されれば、OKです。

ここで、パースペクティブを変えておきましょう。右上のパースペクティブを[RadRails]に変更します。これでウィンドウ下部に[Generators]や[Servers]タブが表示されるはずです。

ここまで出来たら、必要に応じて MySQL の GUI コンソールなどを入れておきましょう。

さあ、環境は整いました。

アプリを作るぞ!

では、なんか作ってみましょうか。
って、私も全くの初心者なので……そもそもこの文書は『覚え書き』だし。

んー、じゃ、簡単な名簿にしましょう(お約束?)。

管理するのは、氏名のみ。ああ、それから別テーブルで所属団体(会社とか)も登録しましょう。テーブル間の接続の勉強になるし。

アプリの名前は、『address』(もっとマシな名前を思いついた人は、そっちにして下さい)。

まず、プロジェクトを作りましょう。
Aptana IDE (以降、RadRails)を立ち上げます。



メニューから[ファイル]->[新規]->[プロジェクト]とたどります。
[Rails Project]を選び、[次へ]をクリック。
プロジェクト名に『address』(か、マシな名前)と入力して[終了]をクリックします。このとき、[Generate Rails application skeleton]と[Create a WEBrick server]にチェックを付けておきます。
しばしの後に、Rails Navigator ペインに[address]とサブディレクトリがわらわらと現れます。
サブディレクトリ[config]を開けると中に[database.yml]ファイルが出来ているはずです。ここでデータベースへの接続のモロモロを設定します。では、database.yml をダブルクリックして開きましょう。
development:、test:、production: と、三つのセクションに、
adapter: mysql
database: address_development
username: root
password:
host: localhost
のような記述が見つかるはずです。
Railsでは、本番環境以外に、開発環境とテスト環境を持てる(みたいな)のですが、良く判らないので、今回は一つだけです。全てのセクションを
adapter: mysql
database: address
username: root
password:
host: localhost
encoding: utf8
としておきます。
最後に追加した [encoding: utf8] は、文字コードの指定です。
ああそうそう、Railsの基本は UTF-8 です。データベースだけでなく、WEBページも、Railsのソースも UTF-8 にしておきましょう。
ソースを UTF-8 で書くには、Rails Navigator ペインの[address]プロジェクトを右クリックし、[プロパティー]を開きます。[テキスト・ファイル・エンコード]を[その他][UTF-8]にしておきます。

テーブルへの接続準備は整っています。が、テーブルがありません。さあ作りましょう。
折角 GUI のツールを入れたんだから(入れてない?)、それを使って――もいいんですが、今回は Rails の機能を使いましょう。それは、migration です。
RadRails のウィンドウ下部のペインを[Generators]に切り替えます。
[migration]を選び、適当な名称を付けます。そうですね、[FirstStep]とでもしておきましょうか。
[Create]にチェックを付けて、[GO]です。
ちょっと間をおいて、コンソール画面に切り替わり、欲しいものが出来上がったメッセージが表示されます。
では、[db]サブディレクトリを開いてみましょう。[migrate]の中に[001_first_step.rb]ファイルが出来ているはずです。001 は、最初のmigration ファイルを表しています。続く名前は…… Rails ではこういうファイル名の付け替えを勝手にやってくれるんですね。
では、ファイルをダブルクリックして開きましょう。
class FirstStep < ActiveRecord::Migration
 def self.up
 end

 def self.down
 end
end
こうなっているはずです。
[self.up]は、作成時、[self.down]は取り消し時に実行する処理です(RadRails から取り消す方法は、知らない。必要ならばコマンドプロンプトから、どうぞ)。
class FirstStep < ActiveRecord::Migration
 def self.up
  options = {
   :options => "ENGINE=MyISAM DEFAULT CHARSET=utf8"
  }

  create_table(:organizations, options) {|table|
   table.column :name , :string , :null => false
   table.column :created_on , :timestamp
   table.column :updated_on , :timestamp
  }

  create_table(:people, options) {|table|
   table.column :name , :string , :null => false
   table.column :orgId , :integer , :null => false
   table.column :created_on , :timestamp
   table.column :updated_on , :timestamp
  }

 end

 def self.down
  drop_table :organizations
  drop_table :people

 end
end
こんな感じにしてみました。organizations、people の2つのテーブルを作ります。
ここには Rails 特有のお約束がいくつか入っています。
まず、テーブル名には複数形を用います。ちなみに、[people]は[person]の複数形です。
また、デフォルトではテーブルには自動インクリメントされる数値フィールド[id]がキーとして付けられます。従って、デフォルトで良ければ、特にキーを指定する必要はありません。
created_onupdated_on という名前のフィールドの値は、データの追加時、変更時に、自動でセットされます。
そうそう、options で、文字コードに UTF-8 を指定しています。

ここで InstantRails を起動しましょう。Apache は使わないので止めてしまっても構いません。肝心なのは MySQL です。



では、001_first_step.rb を右クリックし、[Run Migration]してみましょう。
おおっと、コンソールにエラーが出ました!
rake aborted!
Unknown database 'address'
そう、まだデータベースを作っていませんでした。では、GUI ツールなりコンソールなりを使って、データベースを作っておきましょう。database.yml で指定したユーザーがアクセスできるように権限にも注意しましょう。
MySQL Administrator だと、Create new Schema で作れます。



もう一度、Run Migration してみましょう。今度はうまくいったかな?

テーブルが出来上がったので、そろそろアプリケーションの雛型でも作りましょうか。Rails では、雛型じゃなくて足場、[scaffold]と呼びます。
足場は、テーブル毎に作ります。足場作り担当も[Generators]です。
scaffold を指定し、名前にはテーブル名の単数形を指定します。
まずは[organization](長かったな(^_^ゞ)です。Create にチェックを付けて、[GO]、しばしの後に、色々なものが出来上がります。
続いて[person]です。さて、Rails は person を people の単数形と認識するのでしょうか?



これで何が出来たのかというと、リスト、新規登録、変更、表示などの基本的なWEB画面や付随処理などです。[apps]ディレクトリ以下に、ファイルが増えています。では、確認してみましょう。

Rails では、WEBサーバーの面倒も見てくれます。最初にプロジェクトを作成するときに、[Create a WEBrick server]にチェックを入れましたよね? では、[Servers]タブを見てみましょう。
addressServer なるものがありますね? ポートは何番になっていますか? 3000番? 3001番? では、addressServer を右クリックし、Start しましょう!

ブラウザで、
http://localhost:3000/ (あなたのところでは3001か3002か、別の番号かも知れません)にアクセスしてみましょう。



あれれ? Welcome aboard って、Rails のウェルカム画面ですね。
ではもう一度。今度は
http://localhost:3000/organizations/
にアクセスしてみましょう。



おおっ! 無事に表示されました。愛想のない画面ですが、[New organization]をクリックすれば、ちゃんと登録も出来ます。何か登録しておきましょう。



表示や削除のボタンもあります。Rails、親切ですね。いちいちSQLステートメントを書いていたあの頃がウソの様です。

http://localhost:3000/people/
は、どうでしょう。おお、ちゃんと動きますね。People - Person を認識しているようです。

これで雛型は揃いました。

ちょっと便利に

でも、このままではちょっと不便です。個人を登録する際に、所属を[id]で指定しなければなりません。これでは予め[id]を知っていないと登録できません。ここはやはり、所属の名前で選びたいところです。
早速、改造に掛かりましょう。
では、『所属』と『個人』を関連付けてみましょう。

ここからの作業の多くは、[app]ディレクトリ以下のファイルの変更になります。
[app]以下には、[controllers][helpers][models][views]の各サブディレクトリがあります。何となく、MVC(「Model」「View」「Controller」の3要素を分離させた設計モデル) っぽいですね。まあ、その通りのものですが。

では、[models]の中を開けて下さい。
organization.rb を開きます。
class Organization < ActiveRecord::Base
 has_many :people
end
[has_many :people]を追加します。『Organizationは、たくさんのpeopleを持っているよ』という宣言ですね。

続いて person.rb です。
class Person < ActiveRecord::Base
 belongs_to :organization
end
[belongs_to :organization]を追加します。『Personは、organizationに所属しているよ』という宣言です。

これで両者の関係がはっきりしました。一:多 の関係です(今回は、個人が複数の組織に所属するケースは考えていません)。

サブディレクトリ[views]の中も見てみましょう。さらにディレクトリが出来ていますね。では、[people]を開きましょう。

『足場』では、edit.rhtml と new.rhtml からは _form.rhtml を取り込む様になっています。_form.rhtml をダブルクリックで開いてみましょう。
<p><label for="person_orgId">Orgid</label><br/>
<%= text_field 'person', 'orgId' %></p>
ここで所属を指定するのですが、直接所属の[id]を入力するようになっています。そこで、ここを次のように変更しましょう。
<p><label for="person_orgId">Orgid</label><br/>
<%= select("person", "orgId", Organization.find_all.collect {|e| [ e.name, e.id ] }) %></p>
http://localhost:3000/people/
にアクセスして、誰か登録してみて下さい。どうですか?



created_on、updated_on は、入力しませんから _form.rhtml には不要です。削除しましょう。見出しも日本語にしちゃいましょうか。



とりあえず、_form.rhtml はこんなところでしょうか。
[views]以下の各ファイルに手を入れて、見た目のカスタマイズをしてみて下さい。 カスタマイズした内容はサーバーを再起動しなくてもちゃんと反映されています。すごいですね。生産効率、高いです。

これで一応、目指したものが出来上がりました。自分のP/Cの中でWEBアプリが動いているなんて、まるで小宇宙を手に入れたみたいで、感動です。

機能追加だぞ

でも、もう少しいじってみましょう。折角なので、メアドも登録できるようにしてみましょう。

テーブルにフィールドを追加するにも migration を使います。
RadRails のペインを[Generators]に切り替え[migration]を選び、[mailAddress]と名前を付け、[Create]を選んで、[GO]をクリック。もう慣れました?

[db]-[migrate]の中に[002_mail_address.rb]ファイルが出来ました。
class MailAddres < ActiveRecord::Migration
 def self.up
  add_column(:people, :eMail, :string)
 end

 def self.down
  remove_column(:people, :eMail)
 end
end
こんな感じで、eMail フィールドを追加します。早速 [Run Migration]してみましょう。
続いて、_form.rhtml に
<p><label for="person_eMail">eMail</label><br/>
<%= text_field 'person', 'eMail' %></p>
の様に追加します。
http://localhost:3000/people/
にアクセスすると、リストに項目が増えているはずです。[Edit]で、メアドを登録してみましょう。



ああ、見出しを日本語化し忘れていますね。後で直しておきましょう。

それにしてもリスト表示がウザいですね。list.rhtml も書き換えちゃいましょう。
ついでに、メールも出せるようにしておきます。
<h2>連絡先 一覧</h2>

<table border="1">
 <tr>
  <th>氏名</th>
  <th>所属</th>
  <th>eメール</th>
 </tr>

<% for person in @people %>
 <tr>
  <td><%=h person.send(:name) %></td>
  <td><%=h Organization.find(person.send(:orgId)).name %></td>
  <td><%= mail_to(person.send(:eMail), nil, :subject => "Contact") %></td>

  <td><%= link_to 'Show', :action => 'show', :id => person %></td>
  <td><%= link_to 'Edit', :action => 'edit', :id => person %></td>
  <td><%= link_to 'Destroy', { :action => 'destroy', :id => person }, :confirm => 'Are you sure?', :method => :post %></td>
 </tr>
<% end %>
</table>

<%= link_to 'Previous page', { :page => @person_pages.current.previous } if @person_pages.current.previous %>
<%= link_to 'Next page', { :page => @person_pages.current.next } if @person_pages.current.next %>

<br />

<%= link_to 'New person', :action => 'new' %>
こんなところでしょうか。



メールアドレスをクリックすると、メーラーが起動します。

*外部に晒すときは、メアドをそのまま書かないで下さい。ワームとスパムの嵐に見舞われます。常識ですね。

ところで、[mail_to]の :subject を"ご連絡"などと日本語にしたらメーラーで化けました。これは呼び出されたメーラー(Outlook Express 6)が、二バイト文字をS-JISとしているためのようです。どうしても日本語にしたいときは、
:subject => Kconv.tosjis("ご連絡")
とか、強制的にS-JISにしちゃえばOKみたいです。

この調子で見た目を整えたり、必要なフィールドを追加したり、色々試してみましょう。私も試してみますよ、ええ、頑張って。


MySQL では、「スキーマ」「テーブル」「カラム」って言うんですか、そうですか。DB2/400 (RPG) では「ライブラリ」「データベース」「フィールド」ですかね。
他の文化圏の人、例えばオラクル人やらポスグレ人と話をするときに、結構混乱するんですよ。特に、RPG では「テーブル」って無いでしょ? (いや、あるんですけど、全然別物で)代わりに「データベース」って言うと、彼らは別のものを想像しちゃうですよ。そりゃコッチの文化じゃ「ライブラリ」だね、って言っても、『ナニ、ソレ』だから。
この覚え書きでは、「データベース」「テーブル」「フィールド」使ったけど、判るよね?

トップページを作りたいっ!

ここまでで、http://localhost:3000/organizations/、http://localhost:3000/people/ で、それぞれの一覧ページを表示できるようになりました。
しかし。
http://localhost:3000/ では、相変わらず ウェルカムページが表示されます。ウェルカムページを読むと、
Set up a default route and remove or rename this file
Routes are setup in config/routes.rb.
と、書いてあります。省略時のルートを設定し、このファイルを消すかリネームしろ、ということですね。
ルートの設定は[config/routes.rb]に書け、ということで、早速 routes.rb を見てみましょう。
# You can have the root of your site routed by hooking up ''
# -- just remember to delete public/index.html.
# map.connect '', :controller => "welcome"
''(ブランク)をフックアップすることで、サイトのルート(トップページ)の設定が出来る、ということらしいです。[public/index.html]を消すのを忘れるなよ、とも書いてあります。どうやら、ウェルカムページに書いてあった『this file』とは、[public/index.html]の事のようです。だいぶん見えてきました。
三行目の、[# map.connect '', :controller => "welcome"]は、デフォルト・ルートのサンプルです。ファイルやパスが指定されなかったときは、[welcome]コントローラーを使え、という指示です。
試しに、ここを次のようにしてみましょう。
# You can have the root of your site routed by hooking up ''
# -- just remember to delete public/index.html.
map.connect '', :controller => "people"
http://localhost:3000/ にアクセスしてみましょう。
まだウェルカムページが表示されます。やはり他人の言うことは聞いておくべきですね。[public/index.html]を[public/index.bak]にでもリネームしましょう。
今度はどうですか? うまくいきましたね。いきなり『連絡先 一覧』ページが表示されました。
これでトップページを設置する方法が二つ判りました。一つは、[public/index.html]を置き換えてしまうという方法、もう一つがこのルート設定です。

ちょっと試してみましょう。まず、index.html を置き換える方法です。以下の内容で[public/index.html]を作ってみます。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Address List: Top Page</title>
</head>

<body>
 <center>
  <h2>連絡先管理システム</h2>
  <table border="0">
   <tr>
    <td><a href="/organizations">所属 一覧</a></td>
   </tr>
   <tr>
    <td><a href="/people">連絡先 一覧</a></td>
   </tr>
  </table>
 </center>
</body>
</html>



ちゃんと表示されます。これがトップページを差し替える最も簡単な方法のようです。
折角なので、もう一つの方法も試してみます。ルート書き書き手法です。
では、先ほど作った[public/index.html]は削除して、お馴染みの[Generators]に、コントローラーを作ってもらいましょう。[controller]を選び、名前は[welcome]とします。[GO]!
[app/controllers]に、[welcome_controller.rb]が出来ましたね? ダブルクリックで開きましょう。
class WelcomeController < ApplicationController
 def index
  render :action => 'main'
 end

end
3行追加して、[main.rhtml]を表示するように指示しておきます。
これに合わせて、[views/welcome]に[main.rhtml]ファイルを作ります。
<center>
 <h2>連絡先管理システム</h2>
 <table border="0">
  <tr>
   <td><a href="/organizations">所属 一覧</a></td>
  </tr>
  <tr>
   <td><a href="/people">連絡先 一覧</a></td>
  </tr>
 </table>
</center>
先ほどと同じ内容ですが、ヘッダー部、フッター部が不要です。

そうそう、ルートの設定は[config/routes.rb]に書け、でしたね。
# You can have the root of your site routed by hooking up ''
# -- just remember to delete public/index.html.
map.connect '', :controller => "people"

# You can have the root of your site routed by hooking up ''
# -- just remember to delete public/index.html.
map.connect '', :controller => "welcome"
に、直します。
では、http://localhost:3000/ にアクセスです。
前と同じページが表示されました。どうやら成功のようです。
でも、これではまるでデジャヴ、本当にうまくいったのか、イマイチ自信が持てません。さっきとは少し違うページにしましょう。
welcome_controller.rb をダブルクリックで開きます。
class WelcomeController < ApplicationController
 def index
  main
  render :action => 'main'
 end

 def main
  session[:startTime] = Time.now.to_s
 end

end
ちょっとだけ、追加です。session は、セッションの間有効な変数(ハッシュ)です。『さっきとは少し違うページ』を作るだけなのに、なんで session なんでしょうかね? まあ、いいじゃないですか。
session[:startTime] に現在の日時を入れたので、表示する方も作ります。
main.rhtml ファイルを開きます。
<p><%=h session[:startTime] %></p>
<center>
 <h2>連絡先管理システム</h2>
 <table border="0">
  <tr>
   <td><a href="/organizations">所属 一覧</a></td>
  </tr>
  <tr>
   <td><a href="/people">連絡先 一覧</a></td>
  </tr>
 </table>
</center>
先頭で、session 変数の "startTime" を表示させています。
では、見てみましょう。



左上に開始日時が表示されました。どうやらトップページの表示はこの方式で行けそうです。
また一つ賢くなりました >ジブン。
最初にユーザー認証して、ユーザーの情報は session 変数に保存しておく、なんて使い方が出来そうです。もっとも、ユーザー認証には便利なプラグインがあるらしいので、自分で書くことは無いかも知れません。



これでこの『覚え書き』はおしまいです。
『名簿』アプリなのに名前が address で、しかも住所が無い、というヘンテコなソフトを作りました。住所や電話番号フィールドの追加など、やりたいことはいっぱいあります。皆さんも色々試してみて下さい。


Ruby のホームページがリニューアルされました。Rails ベースのCMS(コンテンツ・マネジメント・システム)、Radiant CMS で構築されています。かっこいいです。
私的にはまだ、CMS といえば XOOPS なんですが、Rails では、Rubricks なんかも有名みたいです。で、Rubricks ちょっと試して見たんですが、Beta版だったせいか、幾つかのモジュールでエラーが出ました。対応するモジュールの数も種類も少ないし、まだ XOOPS の代わりは難しそうです。
その Rubricks を RadRails でいじってみたい、という人は、アーカイブを RadRails のワークスペースに展開し、メニューから[ファイル]-[インポート]とやればOKです。さらに、[Servers]ペインで右クリックし[Add]で WEBrick サーバーを作っておけば、Mongrel の代わりになります。
その他のインストール手順は、付属ドキュメントに従って下さい。

Rubricks に興味を持つ人が増え、便利なモジュールが増えたら、私も XOOPS からの乗り換えを考えます。という訳で、みんな、頑張って!






サイト名: flyman のおもちゃ箱   http://www.kestrel.jp
この記事のURL:   http://www.kestrel.jp/modules/tinyd04/index.php?id=8