トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

Ruby on Rails勉強用メモ/簡易ゲストブックの作成

Ruby on Rails勉強用メモ > 簡易ゲストブックの作成

Railsでゲストブックや掲示板を作るのはどの程度簡単かな?と思って試してみたもの。

Rubyはよく使ってるけどRailsはほぼ初の私は、2時間で出来ました。

参考文献:Amazon.co.jp: Ruby on Rails 逆引きクイックリファレンス Rails 2.0対応

仕様

  • ユーザが入力できるのは、「名前(name)」「メッセージ(text)」の2項目
  • DBに格納されるのは、上記2項目に「発言時刻(time)」を加えた3項目
  • 以上3項目は、いずれもHTMLエンティティ化しない状態の文字列でDBに格納(=タグ除去等の処理はその段階では行わない)
  • これらの情報を格納するモデルの名称は "MessageLog"
  • DBMSとしてSQLite3を利用
  • コントローラの名前は "Messages"(よって、このアプリケーションには http://サーバ名/messages/**** のようなURLでアクセスする)
  • アクション(上記URLの「****」の部分)は以下の3つを作成
    • show: メッセージの投稿フォームおよび、それまでの投稿を表示。メッセージの投稿はアクション "post" が受け取る
    • post: 投稿を受け取り、受領したというメッセージおよび "show" へ戻るためのリンクを表示
    • index(省略時): "show" へリダイレクト

準備

Windows(Vista)上で行ったので、それに合わせてあります。Unix系OSの場合は適宜読み替えて下さい[1]

参考:Ruby on Railsのインストール方法(Windows版) - バリケンのRuby日記 - Rubyist

C:\Users\hiro\rails> gem update --system
(略。Rubygems本体を更新)

C:\Users\hiro\rails> gem install rails
(略。Ruby on Railsおよび関連するライブラリをインストール)

C:\Users\hiro\rails> gem install sqlite3-ruby --version 1.2.3
(略。SQLite3および関連するライブラリをインストール)

その後、SQLite3のWindows版DLLを http://www.sqlite.org/download.html からダウンロードし(Precompiled Binaries For Windows → sqlitedll-3_#_#.zip と進む)、その中のDLLをシステムファイルフォルダにコピーする(Windows Vistaの場合、デフォルトでは C:\Windows\system32)。

※注:sqlite3-rubyを「--version 1.2.3」の指定でインストールしたのは、この記事の執筆当時の最新版(1.2.4)のgemは、Windowsバイナリ版がなかったためである。

プロジェクトの作成

C:\Users\hiro\rails> rails guestbook
(略。基本となるファイルが生成される)

C:\Users\hiro\rails> cd guestbook

C:\Users\hiro\rails\guestbook>

コントローラの作成

コントローラ:受け取ったデータ等を処理する部分

C:\Users\hiro\rails\guestbook> ruby script/generate controller Messages
(略。ファイルが生成される)

guestbook\app\controllers\messages_controller.rb をいじり、とりあえず必要なアクションを3つ作っておく。

class MessagesController < ApplicationController
  def index
  end
  
  def show
  end
  
  def post
  end
end

この状態で、Rails付属の簡易サーバを動かし

C:\Users\hiro\rails\guestbook> ruby script/server

ブラウザで http://localhost:3000/messages/show とか http://localhost:3000/messages/post とかにアクセスする。Railsが出すエラーメッセージ「Template is missing」が見られればOK。

ビューの作成

ビュー:表示の形式

guestbook\app\views\messages に、show.html.erb と post.html.erb を作成する。それぞれがアクションに対応する。

show.html.erb

<html>
<head>
<title>Guestbook</title>
</head>
<body>
<h1>Guestbook</h1>
<h2>投稿する</h2>
<% form_for :sent_message, :url => {:action => "post"} do |f| -%>
<p>名前:<%= f.text_field :name, :size => 15 %></p>
<p>メッセージ<%= f.text_field :text, :size => 50 %></p>
<p><%= f.submit "投稿する" %></p>
<% end -%>

<h2>メッセージ一覧</h2>
<p>まだ表示出来ない!</p>

</body>
</html>

post.html.erb

<html>
<head>
</head>
<body>
<h1>Guestbook</h1>
<p>まだ投稿を受け付けられない!</p>
</body>
</html>

フォームやリンクなど、プログラムの他の部分から影響を受ける内容は、直接タグを打たなくてもよいように関数が多数用意されている(例:form_for)。これにより、プログラム修正時の変更に対処しやすくなっている。

この状態で再度 "ruby script/server" し、ブラウザで http://localhost:3000/messages/show とか http://localhost:3000/messages/post とかにアクセスすると、このERB HTMLに応じた内容が表示される。

モデルの作成

モデル:データを格納する形式。実際にはDBのテーブル等の定義になる。

guestbook\config\database.yml を開くと、以下のような記述がある。

# SQLite version 3.x
#   gem install sqlite3-ruby (not necessary on OS X Leopard)
development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 5
  timeout: 5000
(略)

これがモデル生成時の設定になる。新しいRailsだとsqlite3がデフォルトで指定されるので、いじらずそのまま使う。

実際にモデルを生成する。モデル名の後ろに、名前と型の組を指定する(あとで変更することも可能だが、ここでは省略)。

C:\Users\hiro\rails\guestbook> ruby script/generate model MessageLog name:string text:string time:string

ここで、guestbook\app\models\message_log.rb を開くと、以下のような記述がある。

class MessageLog < ActiveRecord::Base
end

これだけ見ると何も出来ないように見えるが、ActiveRecordは色々とデフォルト値を持っており、それに従ってテーブル名などを指定している場合は、これだけでDBへのアクセスが可能なのである。この場合、MessageLogクラスは「指定されたSQLiteファイルの "message_logs"[2]テーブルにアクセスする」ためのクラスとなる。

コントローラ・ビューにモデルとの連携を記述

guestbook\app\controllers\messages_controller.rb

class MessagesController < ApplicationController
  def index
    # リダイレクトする。
    redirect_to :action => "show"
  end
  
  def show
    # ビュー(show.html.erb)ではDBの内容すべてを用いるため、
    # ここでインスタンス変数に格納しておく。
    # DB全体のデータに対する処理は、クラスメソッドとして定義されている。
    @messages = MessageLog.find(:all)
  end
  
  def post
    # 現在の時刻を取得する。
    # ビュー(post.html.erb)でも用いるため、インスタンス変数に格納しておく。
    @current_time = Time.now.to_s
    
    # フォームから送られた内容は、ローカル変数「params」に格納されている。
    @sent_message = params[:sent_message]
    
    # DBに、現在投稿された項目を追加する。
    # DBの個々の項目に対する処理は、インスタンスメソッドとして定義されている。
    message_log = MessageLog.new(params[:sent_message])
    message_log.time = @current_time
    message_log.save
  end
end

コントローラで参照出来る値のうちビューでも利用したいものは、インスタンス変数に代入しておけばよい。

show.html.erb

<html>
<head>
<title>Guestbook</title>
</head>
<body>
<h1>Guestbook</h1>
<h2>投稿する</h2>
<% form_for :sent_message, :url => {:action => "post"} do |f| -%>
<p>名前:<%= f.text_field :name, :size => 15 %></p>
<p>メッセージ<%= f.text_field :text, :size => 50 %></p>
<p><%= f.submit "投稿する" %></p>
<% end -%>

<h2>メッセージ一覧</h2>
<dl>
<% @messages.each do |entry| -%>
  <dt><strong><%= h entry.name %></strong> (<%= h entry.time %>)</dt>
  <dd><%= h entry.text %></dd>
<% end -%>
</dl>

</body>
</html>

post.html.erb

<html>
<head>
</head>
<body>
<h1>Guestbook</h1>
<p>投稿を受け付けました。</p>
<p>名前:<strong><%= h @sent_message[:name] %></strong></p>
<p>メッセージ:<strong><%= h @sent_message[:text] %></strong></p>
<p>投稿時刻:<strong><%= h @current_time %></strong></p>
<p><%= link_to "戻る", :action => "show" %></p>
</body>
</html>

エラー処理(名前あるいはメッセージが空欄ならエラーを出力する、など)は行っていないが、これで基本的なところは動作する。

スクリーンショットとかなくてすみません><


  • [1]Unix系OSへのSQLite3導入については、恐れ入りますが各位の調査をお願いします。SQLite3のライブラリを以前Linuxに導入したことはあったのですが、今は完全に忘れてしまってます。
  • [2]「MessageLog」の大文字小文字混ぜ書きをアンダースコア区切りに変更し、さらにそれを複数形にしたものである。デフォルトのテーブル名はこの法則で付けられる。