Ruby on Railsの特徴の一つとして、データベースのテーブルと、WEBアプリケーションのクラス構造が、自動的にマッピングされます。そのおかけで、アプリケーションを開発する際に、DBアクセスのためのModelメソッドをほとんど記述する必要がありません。
MVCフレームワーク内で、ORM( Object/Relational Mapping )を実現しているのですが、その恩恵を受けるためには、Railsの作法に則ったDBの使い方をすることがコツのようです。その辺りを、Rails 解説書をもとにメモ。
Railsでの、基本的なMySQLの設定と、Railsプロジェクトの作成は以下の記事を参照。
Ruby on Rails の MySQL設定 Mac OSX
データベースの作成
まずは、データベースのTable作成から。ホーム以下に、Railsというディレクトリを作成しているので以下の場所(tagsはRailsのプロジェクト名)。DBのテーブルを作成するSQL文は、こちらに置いておきます。
Rails/tags/db/create.sql
create.sqlの中身は、こんな感じのSQL文がテーブルの数だけあります。ここでのポイントは、二つあります。
最初は、テーブルの名前のつけかた。アプリケーション内で利用したいクラス・オブジェクト名の複数形をテーブルの名前にします。例えば、WEBアプリケーションで「tag」というクラス・オブジェクトを使いたい場合は、DBのテーブル名を「tags」にしておきます。英語ネイティブの人には直感的なのでしょうが、我々日本人はよく複数形を忘れるので(w。
二つ目は、PRIMARY KEYになるカラムを「id」という名前で作成しておくこと。「tag_id」とかにしてしまうと、Railsアプリケーションで、このテーブルをうまく扱うことができなくなります。とりあえず、アプリケーションから検索したいテーブルのPRIMARY KEYになるカラムは、「id」にしておくのが無難。
Drop table if exists tags; CREATE TABLE tags ( id MEDIUMINT unsigned NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, PRIMARY KEY(id), UNIQUE (name), );テーブルを作成するには、ファイルからSQLを実行
$ mysql tags_development <db/create.sql
テスト(tags_test)や、本番用(tags_production)のデータベースも忘れずにcreateしておきます。
Rails Modelの作成
作成したデータベースのテーブルには、Railsのgenerateコマンドで、自動生成されるアプリケーションの雛形(saffold)からアクセスできます。アプリケーションの雛形を作成するのは以下のコマンド。この時に注意するポイントは、generateする雛形の名前。ここでは、クラス・オブジェクトの名前になるので「単数形」になります。
すでに作成したDBのテーブルは「tags(複数形)」でした。このテーブルにORマッピングされるオブジェクトは、「tag(単数形)」になります。
Modelを作成するコマンド
$ ruby script/generate model Tag
scaffoldを作成するコマンド
$ ruby script/generate scaffold Tag
ずらずら〜と、create文でアプリケーションの雛形が作成されます。そして、ここで作成した雛形アプリケーションにアクセスするには、以下のURL。プロジェクト名とTable名が同じになってしまったので、まぎらわしいですが、「http://localhost/プロジェクト名/オブジェクト名の複数形」ですね。
http://localhost/tags/tags/
そして、WEBブラウザに表示される「New Tag」をクリックすると、自動生成されたフォーム入力画面からデータベースに登録することが可能です。登録されたDBのカラムに対しては、MVCのコントローラーであるTagsControllerから、 @tags や @tagというオブジェクトとして利用が可能です。
class TagsController < ApplicationController
def index
list
render :action => 'list'
end
def list
@tag_pages, @tags = paginate :tag, :per_page => 10
end
def show
@tag = Tag.find(params[:id])
end
RailsにおけるORマッピングと外部制約
解説書によれば、Railsではテーブル間の親子関係にあたる外部制約にも対応するようです。親子関係は、以下のような形で表現されるそう。
Agile Web Development with Rails
![]()
例えば、itemというオブジェクトに対して、複数のreviewが存在する場合、例として以下のようなTable構造があったとして、
CREATE TABLE items ( id MEDIUMINT unsigned NOT NULL AUTO_INCREMENT, title varchar(255) NOT NULL, uri varchar(255) NOT NULL, PRIMARY KEY(id), UNIQUE (uri) ); CREATE TABLE reviews ( id MEDIUMINT NOT NULL AUTO_INCREMENT, item_id MEDIUMINT unsigned NOT NULL, PRIMARY KEY(id), CONSTRAINT fk_reviews_item FOREIGN KEY (item_id) REFERENCES items(id) );
この場合は、app/model/review.rbに以下のように記述する
class Reveiw < ActiveRecord::Base belongs_to :item end
この外部制約とクラスの親子関係が、アプリケーション内でどのようにハンドルされるのかは、まだ勉強不足でよくわかりません。itemをDeleteしたときに、関連するreviewも削除するとかできるのかな?
なんとなく、まとめ
こんな感じで、Railsではデータベースのスキーマと、アプリケーション内のクラス設計が非常に緊密な関係にあります。そのために、アプリケーションをつくる過程で、何度もDBのテーブル構造を変えたくなってしまいます。ただ、generateコマンドによる雛形の自動生成が可能なので、スキーマ修正の手間は軽減されています。
いままでは、最初に色々と考えてテーブルを作成するものの、一度DBアクセス用のモデル層を作成してしまうと、どうしても修正が面倒になってしまっていました。そのために、アプリケーションのクラス構造のほうに、ゴニョゴニョと手を入れて、完成する頃には、同じデータを表しているのに、DBとクラスが違う構造になっていることもよくありました。
Railsは、確かに手間を軽減してくれるフレームワークでもあるのですが、僕のような週末プロブラマーにとっては、「ORマッピングって、こういうことだったのね」というような、色々な気づきがあるので、「やってて面白い感」が強いです。

ブックマーク & はてなスター
コメント