Ruby on Rails ~レールの路線図~

2006.1.21に発表したRuby on Railsのスライドです。12月の週末に初めてrailsに触ったので、まだほんの初歩的、序の口のところです。

21st Jan 2006

堀川 久

http://www.nslabs.jp/

これまでの私

1.Ruby添付のcgi-lib.rb

2.Ruby添付のcgi.rb

3.テンプレートエンジンの探索

4.現在

チュートリアル

Tutorial in Ruby on Rails
http://wiki.rubyonrails.com/rails/pages/Tutorial

以上。

しかし、railsの全体像をつかまないと、自分でアプリケーションを書けません。

試した環境

  • Fedora Core 4 Linuxベース
  • Linux kernel 2.6.15-rc6
  • MySQL 5.0.18 ... Fedora Core 4添付のMySQL 4.1は日本語が扱えなかった
  • djbdns 1.05-test22
  • Apache HTTP Server 2.2.0
  • Ruby 1.8.4 ・・・ /usr/bin/ruby ※要rdocパッケージ

インストール

... apacheの設定は後述

railsと依存パッケージ

Rails 1.0.0

  • Rake 0.6.2 ・・・ Ruby版make
  • Active Support 1.2.5 ... 実用的なクラスと標準ライブラリの拡張
  • Active Record 1.13.2 ... O/Rマッパ
  • Action Pack 1.11.2 ... リクエストからレスポンスまで
  • Action Mailer 1.1.5 ... emailの配送とテストを簡単に
  • Action Web Service (aws) 1.0.0 ... APIの提供

リクエストからレスポンスまで

[Webブラウザ] -> [httpd] -> [ディスパッチャ] -> [コントローラ] <- redirect_to

[モデル] <-> [ビュー] -> [httpd]

MVC

ディスパッチャはrailsが提供。

パス技術
モデル:app/models/Active Record
ビュー:app/views/ERB
コントローラ:app/controllers/Action Pack

※モデルはデータを格納するだけ。ビューにnotifyしたりしない。コントローラが頑張る。

railsでのフロー

  1. ひな形を作る

    rails提供のコマンドを利用

  2. テストを作る

    テストのひな形も作ってくれる

  3. コードを書く -- ひな形を修正

・・・この繰り返し

ディレクトリ構成

$rails <アプリケーションのパス>
  • app/
    • controllers/
    • helpers/
    • models/
    • views/
  • components/
  • config/
  • db/
  • doc/
  • lib/
  • log/
  • public/
  • script/
  • test/
  • vendor/

apacheの設定

cgiで動かしてみる

extra/httpd-vhosts.conf

<VirtualHost *:80>
ServerName rfoto.orange.fruits
DocumentRoot /home/hori/ruby/RFoto/public
UserDir disable
SuexecUserGroup hori hori
ErrorLog /home/hori/ruby/RFoto/log/apache-error_log
CustomLog /home/hori/ruby/RFoto/log/apache-access_log common
</VirtualHost>

DBの設定

config/database.ymlファイル

development:
  adapter: mysql
  database: RFotoDB
  username: rfoto_dbuser
  password: パスワード
  encoding: utf8 ・・・これで文字コードを指定
  socket: /var/lib/mysql/mysql.sock

script/generateコマンド

  • ひな形を生成
  • script/generateで作れるもの:
    • model
    • controller
    • scaffold
    • mailer
    • migration
    • plugin
    • session_migration
    • web_service

scaffold

マスタ編集の一連の処理を生成

$ script/generate scaffold <モデル名> [<コントローラ名>] [<アクション>, ...]

モデル

Active Recordパッケージ;

モデル (2)

$ script/generate model <モデル名>
  • モデル名は、単数形、Pascal case
  • ファイル名は、小文字アンダースコア化したもの
  • app/models/user.rb
    class User < ActiveRecord::Base
    end
    
  • ActiveRecord::Baseから派生させる
  • テーブルのフィールドに対応するメソッドを自動生成
  • saveで行を更新
    u = User.new()
    u.name = “foo”
    u.save
    

DBテーブル

  • テーブル名・・・複数形、小文字アンダースコア
  • 主キー・・・'id'。整数型に限る。MySQLでは、auto_incrementも必要
    id INTEGER UNSIGNED auto_increment PRIMARY KEY
  • 外部キー (FK)は、'単数形+_id'という名前にする。ex) product_id

1:多、多:多

  • 1:多
    • has_many :相手テーブル名
      • 相手テーブルに自エンティティを指すFK
      • いくつかのメソッドを生成
    • belongs_to :相手テーブル名の単数形
      • 自テーブルにあるFKの操作メソッドを生成
  • 1:1
    • has_one :相手テーブル名の単数形
  • 多:多
    • has_and_belongs_to_many :相手テーブル名

(2007.2.21追記。) has_and_belongs_to_many は deprecated (非推奨) になった。多対多は、has_many の:throughオプションを使う。中間テーブルは普通のActiveRecordテーブルとして作る。

複雑なテーブル / レガシーシステム

  • set_table_name 'テーブル名'
  • set_primary_key '主キー名'

    ※複数主キーのときは?

  • find?
  • トランザクション?

コントローラ

  • Action Packパッケージ

    リクエストからレスポンスまでのルーティングを担当

    $ script/generate controller <コントローラ名> [アクション名 ...]
    
  • 名前付け
    コントローラ名:Pascal case。'admin/CreditCard'など'/'で区切って長くできる
    クラス名:コントローラ名+ Controller。パスの部分はモジュール名になる
    ファイル名:クラス名小文字アンダースコア化

アクションの決定

  • URLからアクションが、アクションからビューが自動的に決まる
    • config/routes.rb でURLとアクションの対応付け
    • URL内の各値は、コントローラのparams[:名前]で得られる
    • http://ホスト名/パス/Object/action/パラメータ
    • <パス>にあるObjectControllerクラスのactionメソッド呼び出し
  • ビューはアクションと同名

コントローラクラス

  • ApplicationControllerから派生
    ApplicationController < ActionController::Base
    
  • app/controllers/users_controller.rb

コントローラからモデル操作

モデルオブジェクトのメソッド

  • self.find(主キー)
  • self.new(主キー=nil)
  • save
  • update_attributes(hash)

    フィールドを更新して、saveも行う

  • destroy

コントローラのメソッド

  • render :action=>'アクション名'
  • paginate :users, :per_page=>件数
  • redirect_to :action=>'アクション名'
  • flash[:notice]
  • params[:パラメータ名]

日本語を表示するために

app/controllers/application.rb

class ApplicationController < ActionController::Base
  before_filter :set_charset
  after_filter :response_encoding

  private
  def set_charset
    @headers['Content-Type'] = 'text/html; charset=UTF-8'
  end

  def response_encoding
    #@response.body = NKF.nkf('-s -W -m0', @response.body)
  end
end

ビュー

ファイル名:パス/コントローラ名/アクション名.rhtml

  • app/views/users/_form.rhtml
  • app/views/users/edit.rhtml

ビュー (2)

  • ERBで記述
  • タグの生成(ActionView)
    • start_form_tag :action => 'update', :id => @user
      • <form action="/users/update/1" method="post">
      • コントローラのインスタンス変数が見える
    • submit_tag 'ボタンテキスト'
    • end_form_tag
    • link_to 'リンクテキスト', :action => 'show', :id => @user
    • text_field 'オブジェクト', 'メソッド'

部分レンダリングなど

  • render :partial => 'form'

    _form.rhtmlの内容を出力

  • error_messages_for 'user'
  • HTMLエスケープ
    • <%=h ... %>
    • XSSを発生させないために、忘れないこと。
  • モデルオブジェクトのメソッド
    • content_columns

それから

  • 国際化?
    • テーブルの列名
    • ケータイ?(シフトJIS)
  • セッション管理

    PC(クッキー)、ケータイ(URL)

  • セキュリティ
    • SQL injection
    • ローカル資源へのアクセス
  • viewstate

fin.