Java+Strutsの視点からRailsを捉える

中越智哉
ナレッジエックス
2006/4/1


本記事は2006年に執筆されたものです。RubyやRuby on Rails全般の最新情報は@IT Coding Edgeフォーラムをご参照ください。

Javaプログラマが気になるRailsのキーワード

 Javaエンジニアの皆さんにとって、最近気になるテクノロジーとして「Ruby On Rails(以下、Rails)」が挙げられるのではないでしょうか。

 インターネットを使って、Railsについて少し調べてみると、いろいろと刺激的なキーワードが並んでいることが分かります。例えば、もう誰もが用語として知っているAjaxへの標準対応であったり、「Javaの10倍の開発生産性」「ブログサイトが15分でできる」といったようなパフォーマンスを強調する触れ込みであったり、「DRY」「Convention over Configuration」といったRailsの思想を表す目新しいキーワードであったりします。

 逆に、Railsの概要を紹介する文に必ず書かれている「MVCアーキテクチャへの準拠」は、Javaのフレームワークでは現在ほぼ当たり前といっていい状況ですが、Railsの紹介では強調されているのが目に付くといった点もあります。

 本稿では、これらのキーワードについて、Javaエンジニアの目線から見て、RailsがStrutsのようなフレームワークとどのように違うのかを明らかにすることを主眼に、お互いを比較しながら紹介してみたいと思います。

Ruby On Rails自体についての解説は、「WebプログラマはRailsに乗るべきか?」や、「Rubyでアジャイルプロトタイピング」にもありますので、そちらもぜひご覧ください。

マスターメンテナンスアプリケーションを題材に比較する

 本稿では、簡単なマスターメンテナンスアプリケーションを題材にRailsでのアプリケーションがJava(Strutsを想定)とどのような違いがあるかを説明していきます。このアプリケーションでは「社員マスター」を管理の対象とします。

 今回は簡易版なのでログインなどは対象としません。

■社員マスターメンテナンスを作る

 ではさっそく、業務システムで作成する機会の多い、社員マスターメンテナンス画面を作ってみましょう。簡易なアプリですから、分析とか設計とか、そういう難しい話は取りあえず脇に置くとして、Strutsの場合ですと皆さんは何から作り始めるでしょうか?

社員マスター
テーブル名 M000_Members


項目名 カラム名 NOT NULL制約 主キー
ID id INTEGER あり
社員番号 member_cd INT(10) あり
社員氏名 member_name VARCHAR(30) あり
入社年月日 join_date DATE あり

 簡単な画面遷移図を書いた後で、struts-config.xmlの作成から始める方もいらっしゃるでしょうし、JSPベースで画面を作ってしまう方もいらっしゃるでしょう。それともお気に入りのORM(O/Rマッピングフレームワーク)用の設定ファイルを先に書くでしょうか? まあ順序はともかくとして、書かなければいけないであろう要素は、次のようになるでしょう。

  • アクションコンフィグレーションファイル(struts-config.xml)
  • メッセージリソースファイル
  • JSPファイルを画面分(4画面?)
  • アクションクラス(5〜10クラス)
  • アクションフォームクラス(1〜2クラス)
  • ORMモジュール用のコード(1〜3ファイル)

 すでにStrutsをよく利用している方ならば、テンプレートになり得るサンプルやひな型をお持ちでしょうから、さほど難しい作業ではないと思います。

 Railsの場合はどうでしょうか。本稿にご興味をお持ちの方ならすでにご存じかもしれませんが、Railsには、scaffold(足場と訳されます)と呼ばれる仕組みが標準で備わっています。

 もちろん、完全なものがいきなり出来上がるわけではありませんが、取りあえずの土台になるモジュールは、データベースの接続設定さえしてあれば、下記のscaffoldを実行するだけで一瞬にして出来上がります。

ruby script/generate scaffold m000_member MemberAdmin

画面1 上記のscaffoldを実行したところ

 この1つのコマンドで、以下の機能を備えたアプリケーションが生成されます(画面2)。

  • テーブルの一覧(ページング機能付き)
  • 単票形式のデータ表示
  • 新規登録
  • 編集
  • 削除
画面2 自動生成されたアプリケーション

 あとは、これをベースとしてカスタマイズを施すことで、それらしいアプリケーションを作っていくこともできるのです。scaffoldによって出来上がる主なものは以下です。

  • コントローラクラス(1つ)
  • モデルクラス(1つ)
  • ヘルパークラス(1つ)
  • ビューファイル(5〜6つ)

 それぞれ、どのようなものか詳しく見ていきましょう。

・コントローラクラス

 Railsのscaffoldで生成されるコントローラクラスは、StrutsでいえばちょうどMappingDispatchActionクラスのようなイメージです。どのリクエストに対しても同じクラスを対応させて、リクエスト内容に応じて異なるメソッドを実行させることになります。

  ですのでStrutsでいうところの「コントローラ」であるActionServletとはちょっと役割が違うのですが、Railsではこれをコントローラクラスと呼んでいます。

 scaffoldで作成した場合、1つのクラスの中に、すべての画面に対応するビジネスロジック(マスターメンテナンスなのでロジックといえるほどのものはないのですが)が記述されています。

リスト MemberAdminController.rb
class MemberAdminController < ApplicationController
  def index
    list
    render :action => 'list'
  end

  def list
  @m000_member_pages, @m000_members = paginate :m000_members, :per_page => 10
  end

  def show
    @m000_member = M000Member.find(params[:id])
  end
  def new
    @m000_member = M000Member.new
  end

  def create
    @m000_member = M000Member.new(params[:m000_member])
    if @m000_member.save
      flash[:notice] = 'M000Member was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end


  def edit
    @m000_member = M000Member.find(params[:id])
  end

  def update
    @m000_member = M000Member.find(params[:id])
    if @m000_member.update_attributes(params[:m000_member])
       flash[:notice] = 'M000Member was successfully updated.'
       redirect_to :action => 'show', :id => @m000_member
     else
        render :action => 'edit'
     end
  end

  def destroy
    M000Member.find(params[:id]).destroy
    redirect_to :action => 'list'
  end
end

例えば、

def show
  @m000_member = M000Member.find(params[:id])
end

などと書かれているのがメソッド定義です。では、showというメソッドはいつ、どのようなルールで呼ばれるのでしょうか。

 Strutsならば、「アクションコンフィグレーションファイルを見れば一目瞭然」です。しかし、Railsにはそのような定義ファイルがありません。ではどうやって関連付けているのでしょうか?

 答えは簡単です。Railsでは、Strutsでいう「アクション名」と同じ名前のメソッドがコントローラで呼ばれるという「規約」になっているのです。

 決め打ちか! と不安を感じられた方もいるでしょう。

 しかし、それが、Railsの提唱するキーワード「Convention over Configuration」(設定より規約)なのです。

 コードを書くエンジニアからすると、少々窮屈な気はしますが、その規約を受け入れることによって、設定ファイルをいちいち書く必要がなくなります。確かに、Strusでコーディングしているときは、分かってはいるけれど同じようなパターンのstruts-config.xmlを黙々と書かないといけないことがあるでしょう。Strutsでも、ワイルドカードマッピングという仕組みによって、これと似たようなことが実現できます。Strutsの場合はあくまで開発者の選択ですが、Railsの場合はフレームワークの規約によって決まっているところが大きな違いです。そもそも、フレームワークというのは開発者の自由なコーディングに規約という縛りを与えることによってコーディングの効率化やコード内容の平準化を図るのが主目的といわれていますので、Railsはフレームワークの目的にのっとってこれを推し進めていると考えることができます。

・モデルクラス

 次に、モデルクラスですが、このクラスはオブジェクト/リレーショナル・マッピング(ORM)によってやりとりされる永続データを格納するためのクラスです。Railsでは、ORMとしてActiveRecordというフレームワークをあらかじめバンドルしていますので、通常はActiveRecordを利用することになるでしょう。

 scaffoldによって生成されるモデルクラスの記述はとてもシンプルです。

class M000Member < ActiveRecord::Base
end

 いくらシンプルでもクラスの本体に何も記述がないように見えますので、Rubyの文法をご存じないJavaプログラマの方でも、なんとなくこのクラスが何かの基底クラスの継承であることは予想できるのではないでしょうか?

 ですが、これだけでは、永続化対象のテーブルごとに異なるはずの

  • どんなテーブルと結び付いているか
  • アクセサメソッド(getter/setter)がどんなものか
  • 永続化するときのプライマリキーは何なのか

が全く読み取れません。StrutsやJava用ORMの感覚ですと、どこか別な場所に設定ファイルが自動生成されており、それを見れば分かる、もしくは必要があればそこを書き換えれば対応できる、と考えてしまうのですが、やはりRailsにはそのような設定ファイルはなく、これもいくつかの「規約」によって置き換えられているのです。

  • アクセスするテーブル名は、クラス名を複数形にしたもの
  • カラム名と同じ名前のアクセサメソッドが定義なしで利用できる
  • プライマリキーは「id」という数値型のカラムを前提とする

 コントローラの規約については、納得できる方でも、モデルクラスのこの規約には少々違和感を覚えられるのではないでしょうか。私も最初は強い違和感を覚えました。テーブル名が複数形の名詞、プライマリキーの前提などは、汎用性、柔軟性という面ではかなり縛りの厳しい規約です。

 Strutsの場合、モデルの構築に関してはHibernateやS2DaoなどのORMとの組み合わせが前提となりますので、強い規約を設けようにも組み合わせる相手次第になってしまうのですが、その点ではORM自体をバンドルしているRailsはフレームワークとしての規約に対する思想を徹底しやすく、フレームワーク全体としての統制を保ちやすくなっているといえるでしょう。

余談ですが、ActiveRecordの記述の仕方は、SeasarのS2Daoのやり方と似ているところがあり、S2Daoをご存じの方ですとより理解が早いかもしれません。S2Daoについては「Seasarプロジェクトの全貌を探る」を参照ください。

・ビュー

 ビューに関しては、Javaエンジニアの方にとって最もなじみやすい部分でしょう。StrutsとRailsを比べたときに、最もよく似ているのがERb(Embedded Ruby)によるViewの構築でしょう。ERbでは、JSPと同じアプローチで動的なViewを記述することができるのです。RailsのビューはRHTMLという拡張子で作成しますが、文法的にはJSPに非常に近いものです。例えば、scaffoldで作成された、list.rhtmlというソースの一部を抜粋したものが以下のリストですが、タグ内の文法にRubyとJavaの違いはあるものの雰囲気はJSPとそっくりです。

<h1>Listing m000_members</h1>

<table>
 <tr>
 <% for column in M000Member.content_columns %>
   <th><%= column.human_name %></th>
 <% end %>
 </tr>

 Javaエンジニアの方でしたらすでにお分かりのように、<% 〜 %>が、コードの実行部(JSPでいうところのScriptlet)、<%= 〜 %>が、評価結果の表示(JSPでいうところのExpression)になっています。

 例えば、5行目から7行目で、forループによってcolumnというオブジェクトのhuman_nameという属性値を表示させていることは、なんとなく読み取っていただけるのではないでしょうか。

 これらのRHTMLファイルは、コントローラクラスでの処理が終わった後に、Strutsでいうところのアクション名と同じ名称のものが選ばれ、画面のレンダリングを行います。これも、Railsの規約です。ですから、Strutsのように<forward>タグでフォワード名と物理パスを対応させる記述をする必要はありません。

 scaffoldを使ったサンプルを見ていただくことで、RailsアプリケーションのMVCそれぞれにおけるごく基本的な動作についてはお分かりいただけたのではないでしょうか。

1/2

 INDEX

Javaから見たRuby on Rails
Page1
Javaプログラマが気になるRailsのキーワード
マスターメンテナンスアプリケーションを題材に比較してみる
  Page2
RailsとStrutsの比較を整理する
JavaエンジニアはRailsとどう付き合うべきか?





Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間