54
Ruby on Railsによる Webアプリケーション開発 島根大学 2008-12-12 大場寧子 株式会社万葉 大場光一郎 伊藤忠テクノソリューションズ株式会社 1

Shimane2008

  • Upload
    nay

  • View
    1.314

  • Download
    0

Embed Size (px)

DESCRIPTION

Presentation of a seminar in Shimane Univ.

Citation preview

Page 1: Shimane2008

Ruby on RailsによるWebアプリケーション開発

島根大学2008-12-12

大場寧子株式会社万葉

大場光一郎伊藤忠テクノソリューションズ株式会社

1

Page 2: Shimane2008

自己紹介

•大場寧子•大場光一郎

2

Page 3: Shimane2008

RoR逆引きクイックリファレンス

•大場寧子•大場光一郎•久保優子

毎日コミュニケーションズ

3

Page 4: Shimane2008

今日の課題•掲示板システムの開発•TDD(テスト駆動開発)•Scaffoldを使わない•RESTful

4

Page 5: Shimane2008

必要な作業•プロジェクトの作成•データベースの作成•テストの書き方を覚える•モデル(掲示板記事)の実装

5

Page 6: Shimane2008

bbsプロジェクトの作成

•デフォルトではデータベースとしてsqlite3が選択される。-dオプションでmysqlを指定する

> rails -d mysql bbs

6

Page 7: Shimane2008

データベースを作る

> rake db:create

•※mysqladmin でbbs_developmentを作るのと同じ

•Rails 2.0 で追加された便利なタスク

7

Page 8: Shimane2008

要件を考える

•一種類だけの掲示板•上部に投稿フォーム•ポストした記事が新しい順に表示される

•指定した記事を削除できる

入力欄

投稿

8

Page 9: Shimane2008

モデル設計入力欄

投稿 記事(Entry)

•投稿者の名前•投稿日時•本文

9

Page 10: Shimane2008

モデルの作成(1)generateスクリプトでモデル、ユニットテスト、マイグレーションを作成(2)マイグレーションを実行

10

Page 11: Shimane2008

generateコマンドでモデルを作成する

モデルクラス、テストファイル、マイグレーションファイルが作成される

> ruby script/generate model Entry user_name:string body:text

11

Page 12: Shimane2008

マイグレーションとは

•データベースへの変更を、変更のたびにRubyコードで記述して保存しておく

•開発者全員で共有できる12

Page 13: Shimane2008

生成されたマイグレーションdb/migrate/20081212XXXXXX_create_entries.rb

class CreateEntries < ActiveRecord::Migration def self.up create_table :entries do |t| t.string user_name t.text body t.timestamps end end

def self.down drop_table :entries endend

投稿者を格納するuser_nameカラム

本文を格納するbodyカラム

バージョンアップ(テーブル作成)

バージョンダウン(テーブル削除)

13

Page 14: Shimane2008

マイグレーションの実行

•バージョンを上げる> rake db:migrate

•バージョンを下げて上げる(最後のマイグレーションファイルを実行しなおす)

> rake db:migrate:redo14

Page 15: Shimane2008

モデルが作成できたので

•次は実装(コードを書く)•本当に実装するまえに、満たすべき理想の動作(仕様)をテストに書く

15

Page 16: Shimane2008

Railsのテスト•3種類のテストがある•ユニットテスト•ファンクショナルテスト•インテグレーションテスト

16

Page 17: Shimane2008

テストの実行•テストDBを作成する> rake db:create RAILS_ENV=test

•ユニットテストを実行する> rake test:units

17

Page 18: Shimane2008

テストの成功

•tests - テストメソッドの数•assertions - アサーションの数•failures - 想定と違う結果になった数•errors - エラー(例外)発生数

1 tests, 1 assertions, 0 failures, 0 errors

18

Page 19: Shimane2008

アサーション•assertする=強く断言する•あるべき動作を記述•違反したら知らせてくれる

assert foofooはtrueのはずassert_equal 3, foofooは3のはず

19

Page 20: Shimane2008

デフォルトのユニットテストコード

require 'test_helper'

class EntryTest < ActiveSupport::TestCase # Replace this with your real tests. def test_truth assert true endend

必ず成功するダミーのテストが自動生成されている

test/unit/entry_test.rb

trueは必ずtrue常にアサーションどおり

20

Page 21: Shimane2008

Entryモデルの本当のテストを書こう

•満たすべき仕様•本文が空なら検証エラーとなること

21

Page 22: Shimane2008

検証とは•モデルがデータベースに登録される前に、属性(Attribute)の値が正しいかチェックすること

•検証エラーになったら、保存されない•Railsが便利な仕組みを提供

22

Page 23: Shimane2008

検証は保存前に自動的に行われる属性の代入

検証

保存

属性の代入

失敗falseを返す

save

成功trueを返す

23

Page 24: Shimane2008

Entryの検証•本文が空のとき検証エラーとなる•body属性の中身が’’ならsaveメソッドの返り値がfalseになること

entry = Entry.new( :user_name => "太郎 ", :body => "")entry.save # ←この返り値がfalseになってほしい

24

Page 25: Shimane2008

テストを書こう

require 'test_helper'

class EntryTest < ActiveSupport::TestCase # Replace this with your real tests. def test_truth assert true endend

デフォルトのテストコードを削除する

25

Page 26: Shimane2008

テストを書こうrequire 'test_helper'

class EntryTest < ActiveSupport::TestCase def test_empty_body entry = Entry.new( :user_name => "太郎 ", :body => ""); assert_equal false, entry.save endend

追加

26

Page 27: Shimane2008

テストの失敗

まだEntryの検証を実装していないので、このテストは failure となるはず。

つまり、bodyが空文字でもデータベースに保存できてしまっている。

1 tests, 1 assertions, 1 failures, 0 errors

27

Page 28: Shimane2008

テストが通るようにモデルの検証を実装しよう•bodyが空文字(またはnil)なら検証で失敗して保存されないようにする

class Entry < ActiveRecord::Base validates_presence_of :bodyend

28

Page 29: Shimane2008

実装したらもう一度テストを実行

•成功!1 tests, 1 assertions, 0 failures, 0 errors

29

Page 30: Shimane2008

テスト駆動開発新機能のテストを書く(失敗する)

新機能を実装する

テストが成功する

30

Page 31: Shimane2008

TDDのメリット•リズミカルな開発•コードをメンテナンスしやすい•コードを変更したとき、不具合が発生していないかチェックできる

•仕様(正しい動作)を理解しやすい31

Page 32: Shimane2008

掲示板を作ろう(続き)

•モデルは用意した•コントローラとビューを作ろう

32

Page 33: Shimane2008

コントローラの設計•なにごとも設計から•コントローラの設計は、URLの設計

•掲示板システムのあるべきURLとは?

33

Page 34: Shimane2008

掲示板のURL入力フォームと記事一覧/entries/index記事の投稿/entries/create・・・このスタイルはもう古い

34

Page 35: Shimane2008

HTTPメソッド•HTTPには4つのメソッドがある•GET•POST•PUT•DELETE

35

Page 36: Shimane2008

URL+メソッドGET /entries/3

記事3を取得する

DELETE /enrteis/3

記事3を削除する

PUT /entries/3

記事3を変更する

36

Page 37: Shimane2008

RESTful•URLは「リソース」を表す•例えば「記事」がリソース•HTTPメソッドは動詞を表す•美しいURL•統一的なI/F

37

Page 38: Shimane2008

RESTfulな掲示板システム

入力フォームと記事一覧GET /entries記事の投稿POST /entries

38

Page 39: Shimane2008

コントローラ・アクションとのマッピング

•Railsでは routes.rb に指定

ActionController::Routing::Routes.draw do |map|

map.resouces :entries

end

39

Page 40: Shimane2008

map.resources :entries

意味 HTTPメソッド URL アクション

一覧 GET /entries index

登録フォーム表示 GET /entries/new new

登録 POST /entries create

IDが17の記事を表示 GET /entries/17 showIDが17の記事の変更フォーム表示 GET /entries/17/edit edit

IDが17の記事を変更 PUT /entries/17 update

IDが17の記事を削除 DELETE /entries/17 destroy

コントローラ:EntriesController

40

Page 41: Shimane2008

URLの生成•map.resourcesによって、専用のURL生成メソッドが用意される

URL URLを生成する専用メソッド

/entries entries_path

/entries/new new_entry_path

/entries/17 entry_path(entry)

/entries/17/edit edit_entry_path(entry)

link_to "掲示板はこちら", :controller => "entries", :action => "index"

link_to "掲示板はこちら", entries_path41

Page 42: Shimane2008

我々の課題では意味 HTTP

メソッド URL アクション

一覧と登録フォーム表示 GET /entries index

登録 POST /entries create

IDが17の記事を削除 DELETE /entries/17 destroy

上記の範囲だけを意識して作っていきます42

Page 43: Shimane2008

コントローラの作成

> ruby script/generate controller entries index create destroy

記事を一覧、投稿、削除するためのコントローラをアクション付きで作成します

43

Page 44: Shimane2008

演習1.index アクションと画面を実装する2.create アクションを実装する3.destroy アクションを実装する(余裕がある人のみ)

44

Page 45: Shimane2008

参考URL•Rails APIリファレンス•http://api.rubyonrails.org/•Ruby リファレンス•http://www.ruby-lang.org/ja/man/

45

Page 46: Shimane2008

あとは•自由につくってかまいません•この後のヒントを参考にしてください•講師を呼んで聞いてください•やり方がわからない•エラーが出てわからない•何が分からないのか分からない•なぜ動いているのか分からない etc...

46

Page 47: Shimane2008

ヒント47

Page 48: Shimane2008

indexアクション•データベースからEntryモデルのリスト@entriesを投稿日時の新しい順に取得

•投稿フォームのための新しいEntryオブジェクトを@entryとして用意する

48

Page 49: Shimane2008

投稿日時順の取得

@entries = Entry.find(:all, :order => "created_at desc")

検索時に、:order オプションで順序を指定する。大きい順(降順)なら desc を指定する。

49

Page 50: Shimane2008

index.html.erb(一覧&投稿画面)

•HTMLとしての体裁•上部に@entryを利用した投稿フォーム

•下部に@entriesを利用した一覧の表示

50

Page 51: Shimane2008

index.html.erb の構造の例

<html> <body>

<% form_for :entry do -%> ...... 投稿フォーム ...... <% end -%>

<% for entry in @entries do -%> ....... 1件ずつ記事を表示 ....... <% end -%>

</body></html>

51

Page 52: Shimane2008

createアクション•ユーザー名・本文をリクエストから取得

•Entryオブジェクトを作成•データベースに保存(検証失敗なら保存されない)

•index画面にリダイレクト52

Page 53: Shimane2008

削除機能•index.html.erbで、削除アクションのためのリンクを記事ごとに張っておく

•destroyアクションで指定された記事を削除して、index画面にリダイレクト

link_to "削除", entry_path(entry), :method => :delete

53

Page 54: Shimane2008

まとめ•開発手法のひとつとしてTDDがある•Railsにはテストフレームワークが含まれている

•最近のWebアプリケーションではRESTfulという考え方がある

•RailsはRESTfulを強力にサポート

54