SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

RailsでWikiシステムを作成する

Ruby on RailsによるWebアプリケーション作成の実例

ダウンロード サンプルソース (76.1 KB)

モデルのコードの単体テスト

 モデルのコードをコントローラクラスに挿入する前に、すべてのメソッドが期待どおりに動作するかを確認するために単体テストを実施します。通常、単体テストはメソッドを個別にテストする小規模なものが望ましいのですが、ここでは、複数のテストを単体テストファイル「test/unit/wiki_test.rb」内のtest_wikiという1つのメソッドにまとめて実施します。test_wikiメソッドでは、Wikiモデルクラスのsavefinddeleteexists?の各メソッドをテストします。以下に「wiki_test.rb」ファイルから抜粋したコードを示します。

# Ensure file doesn't exist (yet)
assert !File.exists?(getfullpath(@filename))

# Test save and find
Wiki.save @filename, DEFAULT_TEXT
assert File.exists?(getfullpath(@filename))
text = Wiki.find(@filename)
assert_equal DEFAULT_TEXT, text

# Test delete
Wiki.delete @filename

# Test exists?
assert !Wiki.exists?(@filename)

 ここで、データベースを使用しないRailsアプリケーションをテストするときに発生するいくつかの問題と、その解決方法について考える必要があります。通常、モデルクラスの単体テストは、Railsアプリケーションのトップレベルのディレクトリからrake test:unitsコマンド(以前のバージョンではrake test_units)を実行して開始します。このときRailsはデフォルトでデータベースに接続しようとしますが、RailsWikiアプリケーションはデータベースを使用しないので、この部分をうまく機能させるために2つの変更が必要です(詳細は、Jay Fieldsのブログ記事「Ruby on Rails Unit Tests」を参照)。

 まず、lib/tasksの下に拡張子.rakeで終わるファイルを配置する必要があります。これには、本稿のダウンロードファイルに含まれている「testing.rake」というファイルを使用します。このファイルには、次のRubyコードが含まれています。

Rake::Task[:'test:units'].prerequisites.clear

 次に、「test/test_helper.rb」ファイルのコードを次のように変更します。

ENV["RAILS_ENV"] = "test"
 require File.expand_path(File.dirname(__FILE__) \
          + "/../config/environment")
 require 'application'
 require 'test/unit'
 require 'action_controller/test_process'
 require 'breakpoint'

 ここでrake test:unitsコマンドを実行すると、次のような出力が生成されます。

Started
.
Finished in 0.094 seconds.

1 tests, 5 assertions, 0 failures, 0 errors

モデル、ビュー、コントローラのコードを統合する

 Wikiモデルクラスのコーディングとテストが完了したら、モデル、ビュー、コントローラのコードを統合します。リスト2に、WikiControllerクラスの完全なコードを示します(このクラスは「app/controllers/wiki_controller.rb」にあります)。

リスト2 WikiControllerクラス
# This is the front/main controller for the Wiki application
# Author: Anil Hemrajani
# Date: Feb, 2007
class WikiController < ApplicationController
  layout "wiki" , :except => [ :index, :print ]

  def initialize
    Wiki.basedir WIKI_DIR
  end

  def index
    @filelist = Wiki.find_wikis
  end

  def edit
    get_content
  end

  def view
    get_content
  end

  def print
    get_content
  end

  def help
    @filename = get_filename params[:f] # need this for other actions
  end

  # create new wiki file
  def create
    @filename = get_filename params[:f]
    if Wiki.exists?(@filename)
       flash[:error] = 
"File '#{@filename}' already exists; use Open instead of Create."
       redirect_to :action => :index
    else
      Wiki.save @filename, ""
      redirect_to :action => :view, :f => @filename
    end
  end

  # delete existing wiki file
  def delete
    if params[:f].nil? || params[:f].empty?
       flash[:error] = "File parameter not specified."
       redirect_to :action => :index
    else
      @filename = get_filename params[:f]
      Wiki.delete @filename
      redirect_to :action => :index
    end
  end

  # save existing wiki file
  def save
    @filename = get_filename params[:f]
    content = params[:c]
    p @filename
    p content
    Wiki.save @filename, content
    redirect_to :action => :view, :f => params[:f]
  end

  private
  def get_filename(f)
    f = "untitled" if (f.nil? || f.empty?)
    f
  end

  # load file into @content using param :f; for errors go to index page
  def get_content
    begin
      @filename = get_filename params[:f]
      @filestat = Wiki.attributes @filename
      @content = Wiki.find @filename
      rescue Errno::ENOENT => exception
           flash[:error] = exception
           redirect_to :action => :index
    end
  end
end

 先ほど、Railsのscript/generate controllerコマンドを実行したとき、いくつかのスタブファイルが生成されたことを思い出してください。ただし今回の例では、生成されたメソッドにコードを追加し、さらにいくつかのメソッドを追加しました。新たに追加したメソッドは、ビューに関連付けられるものではなく、他のビューから利用される特定のアクションとして機能するものです。WikiControllerには、initializeindexeditviewprinthelpcreatedeletesaveというpublicメソッドが含まれています。これらのメソッドの一部を詳しく見てみましょう。

  • initializeメソッド
  • Wikiファイルを格納するディレクトリ名を設定します。この名前は、「config/environment.rb」ファイルでWIKI_DIRプロパティを介して構成されます。Wikiファイルを必要に応じて別の適切なディレクトリの下に保存したくなった場合は、この設定だけを変更すれば済みます。
    WIKI_DIR = "/tmp/railswiki"
    
  • indexメソッド
  • Wiki.find_wikisを呼び出して既存のWikiファイル名のリストを生成し、そのリストをインスタンス変数@filelistを介して「index.rhtml」ビューに渡します。このビューは、配列をループ処理し、処理結果をHTMLの<SELECT>ドロップダウンリストに設定します。
    <select name="f">
        <% @filelist.each do |file| %>
            <option><%= file %></option>
                <% end %>
    </select>
    
  • edit、view、printの各メソッド
  • 単にget_contentという内部(private)メソッドを呼び出すだけです。get_contentは、リクエストされたファイルを読み込み、そのファイルの属性と内容をそれぞれインスタンス変数@filestat@contentを介して対応するビューに渡します。以下に使用例を示します。
    def get_content
      begin
        @filename = get_filename params[:f]
        @filestat = Wiki.attributes @filename
        @content = Wiki.find @filename
        rescue Errno::ENOENT => exception
             flash[:error] = exception
             redirect_to :action => :index
      end
    end
    

 get_contentメソッドは、リクエストされたファイルの内容と属性を読み込む他に、ページをインデックスページにリダイレクトし、例外が発生した場合にはエラーメッセージを表示します。エラーメッセージは、Railsのflash機能(実体はアプリケーションエラーを格納するハッシュ)を使用して設定します。

 コントローラがビューにコントロールを渡すと、ビューは単にインスタンス変数@contentの内容を表示します。例えば、「view.rhtml」テンプレートに含まれているファイル全体として1行しかないコードでは、Wikiファイルの内容を表示するだけでなく、表示する前に内容をto_htmlというヘルパーメソッドを使用して変換します。

<%= to_html @content %>

 to_htmlヘルパーメソッドは、Railsが生成するヘルパーモジュール「app/helpers/wiki_helper.rb」ファイル内にあります(ヘルパーモジュールはビューで使用するメソッドを作成するのに便利です)。また、このファイルは、未加工のWikiファイルをHTMLに変換する手順を含み、前に説明したRedClothというgemの動作が開始する場所でもあります。以下に、「wiki_helper.rb」に含まれる、このコードの内容を示します。

require 'redcloth'

module WikiHelper
  # parse and return data as HTML
  def to_html(rawtext)
    return "" if rawtext.nil?

    r = RedCloth.new rawtext
    r.to_html
  end
end

次のページ
その他の注目すべきファイル

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Anil Hemrajani(Anil Hemrajani)

20年に及ぶプログラミング歴を持つ。多くの記事や一般読者向けの本を執筆し、業界関連の賞を多数受賞。世界の4大陸で講演を行い、ある有名な開発者コミュニティを創設した経験を持ち、成功企業の経営にも携わる。現在は独立コンサルタントとして活動中。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1343 2007/06/04 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー