[[Ruby on Rails/第11回勉強会 - RESTful Rails Development]]

&pgid;

** Ruby on Rails勉強会一覧 [#e49b3032]
#ls2(Ruby on Rails)

** 第11回勉強会のネタ [#g66b14da]
ネタもとは下記です。

b-simple.de - Ruby on Rails, Entwicklung, Coaching und mehr!
http://www.b-simple.de/documents

** 日時 [#h027fa8b]
- 2006/04/13(金) 

** 参加者 [#zbecd88f]

#blikimore

** 動画 [#s9f9b274]

** RESTful Rails [#o85deb23]
- HTTPはGETやPOSTメソッドだけでなく、PUT, DELETEメソッドもある
- RESTとは、簡単にいうとHTTPのGET, POSTだけでなく, PUT, DELETEを使ったやり方である
- Rails 1.2ではRESTがサポートされた
- このチュートリアルはRESTのコンセプトと背景の短い紹介からはじまる
- RailsのScaffoldを使うと見ることができるREST-Controllerとmodelは、RESTful Railsの開発の理解を助けてくれる
- 次にREST Routingとよばれる機能の説明をする。
- Nested Resourcesの章はより上級な内容で、どのようにREST-URLのコンセプトに反せずに、親子関係にあるリソースがネストされるかについて説明する
- このチュートリアルの終わりは、RESTとAJAXについての説明だ
- RESTfulなアプリケーションをテストし、クライアントサイドのRESTの一部である、ActiveResourceを紹介する

** RESTとはなにか? [#u9c07902]
- RESTという言葉の名づけ親は [[Roy Fielding:http://yohei-y.blogspot.com/2005/04/rest_23.html]] だ。
- Representational State Transferの略だ。
- RESTは標準的HTTPメソッドであるGET, POST, PUT, DELETEを使用してWebのリソースを要求し、操作するWebアプリケーションのための、アーキテクチャパラダイムを説明する。
- RESTではリソースはHTTP経由でURLでアドレス付けして要求が可能だ。
- リソースは、クライアントの呼び出しに応じて、HTMLやXMLやRSSのような異なったフォーマットで表現できる。
- REST-URLsはユニークだ
- リソースURLは、これまでのRailsのアプリとは違い、コントローラとそれに対応するActionによって決まるのではなく、リソース自身によって決定される。
 (図1.1)
- 図1.1では、3つのリソースすべては、URLの始まりのidentical partによって住所付けられ、それぞれはそのリソースのIDによってフォローされる。
- Railsではコントローラとモデルの組み合わせてリソースを表現する。
- テクニカルな立場からいうと、図1.1のプロジェクトリソースはProjectControllerとActiveRecordを継承したクラス「Project」のインスタンスを操作することによって応答できる

** なぜREST? [#ue4f4c7f]
- MVC-Conseptを使用して2年間Railsアプリケーションをとてもsuccessfullyに開発してきていることを心に保っているとき、これはよい質問だ。
- RESTベースのアプリケーション次の特徴がある
-- きれいなURL。
REST-URLはアクションではなくリソースを表現している。
URLはいつも同じフォーマットをもつ。
最初にコントローラーがきて、それから参照されるリソースのIDがくる
要求された操作はURLから隠され、HTTP メソッドで表現される
-- 異なった応答フォーマット
RESTコントローラのアクションは異なった応答フォーマットを返すことができる。
クライアントの要求に依存して、同じアクションがHTML, XML, RSSを返すことができるようになる。
-- コード量が少ない
複数のクライアントを補足できる開発はDRYの意味においてrepetitionをavoidし、コントローラーがより少ないコードもつ結果となる
-- CRUD指向コントローラ
各コントローラが一つのリソースタイプの操作に対して応答可能であるという方法において、コントローラとリソースは解けて一緒に一つ単位になる
-- 明確なアプリケーション設計
RESTfulな開発は明確なコンセプトの結果となり、操作可能なアプリケーションのデザインになる
-- このチュートリアルの4番目の章は、例のヘルプを使って、上記の名前付けされた特徴のすべてを明確にする


** What's New [#k109b441]
- もし、あなたが、RESTに基づいたアプリケーション設計があなたの下過去の開発経験を利用できなくすると考えているなら、私達はあなたをassureすることができる、すなわち、そんなことはない。
- RESTは、まだMVCに基づいているし、技術的観点で見て下記、の新しい技術へreducedされることができる

-- コントローラのコードにおいてrespond_toを利用する
-- linkとformのための新しいhelperメソッドが提供されている
-- コントローラリダイレクトにおけるURL-Methodの利用
-- routes.rbの中のresourceメソッドから生成される新しい新しい経路

あなたは一度RESTを理解し、その技術を利用すれば、RESTfulアプリケーションの設計は次の標準となるだろう。


** Preparations [#tb2e9365]
- 私たちは、私たちの本RapidWeb Development mit Ruby on Railsの例である、プロジェクト管理アプリケーション「Ontrack」の文脈と一緒の中で、Railsの新しい特定の特徴について説明していきます。
- 私たちは完全なアプリケーションをここでは開発しないだろうが、RESTコンセプトのための技術的な環境を作成するために同じ技術を利用します。
- まず、私たちのRailsプロジェクトの生成をはじめましょう
 > rails ontrack
下記のようにdevelopmentとtestのデータベースを作成します
 > mysql -u rails
 Enter password:
 mysql> create database ontrack_development;
 mysql> create database ontrack_test;
 mysql> quit

** Rails 1.2 [#af4a9054]
-私たちは、すべての読者がRails1.2をインストールしたいとおもっていないかもしれないと思います。
-そこで私たちは、私たちのontrackの例のみが新しいバージョンをつかうように、プロジェクトベースの1.2のRailsインストレーションをすることをおすすめする。
- ドキュメントにそってRails1.2のタグはrel_1-2-1と名づけられる。
  > cd ontrack
  > rake rails:freeze:edge TAG=rel_1-2-1
- 別のRailsのより新しいバージョンをインストールする情報はrailsのWebサイト、http://www.rubyonrails.orgで見つかる。

** Resource Scaffolding [#qca792a0]
- REST指向のRails開発は、新しいscaffoldジェネレータであるscaffold resourceから作成される、リソース「Project」とともに簡単に描くことができる。
- ジェネレータは、リソース名である「project」というパラメータとオプショナルなモデルの属性のリストと、それらのタイプを与えられる
- これらの属性はデータベースのマイグレーションスクリプトと、作成されるビューのappropriateフィールドもまた必要とされる。

 ruby script/generate scaffold_resource project name:string desc:text

 exists app/controllers/
 exists app/helpers/
 create app/views/projects
 exists test/functional/
 exists test/unit/
 create app/views/projects/index.rhtml
 create app/views/projects/show.rhtml
 create app/views/projects/new.rhtml
 create app/views/projects/edit.rhtml
 create app/views/layouts/projects.rhtml
 create public/stylesheets/scaffold.
 create app/models/project.rb
 create app/controllers/projects_controller.
 create test/functional/projects_controller_
 create app/helpers/projects_helper.
 create test/unit/project_test.rb
 create test/fixtures/projects.yml
 create db/migrate
 create db/migrate/001_create_projects.
 route map.resources :projects

- ジェネレータはモデルだけでなく、コントローラ、ビューそして、機能的なマイグレーションスクリプトと新しいマッピングエントリ map.resources :projects をconfig/routes.rbの中に、生成した。

- それは、私たちのコントローラーがResultfulなURLに対して応答できるようなマッピングのエントリーだ。


** The Model [#o6c42584]

- 私たちは最初に言ったように、RESTのリソースは、コントローラとモデルのコンビネーションの文脈である。
- モデルは、通常のActiveRecord::Base:を継承したActiveRecordクラスだ。
  class Project < ActiveRecord::Base
  end
- なので、モデルの場合は、なにも新しいことを学ぶことはない。
しかし、データベースのテーブルを作るのは忘れないように。
  > rake db:migrate


** The Controller [#x6f8e24f]

- 生成されたProjectsControllerは、Projectリソースを操作するする、CRUD-Controllerだ。
- これは、コントローラは正確に一つのリソースタイプに属し、四つのCRUDの操作それぞれの設計されたアクションを提供することを意味する。
 class ProjectsController < ApplicationController
   # GET /projects
   # GET /projects.xml
   def index...
   # GET /projects/1
   # GET /projects/1.xml
   def show...
   # GET /projects/new
   def new...
   # GET /projects/1;edit
   def edit...
   # POST /projects
   # POST /projects.xml
   def create...
   # PUT /projects/1
   # PUT /projects/1.xml
   def update...
   end
   # DELETE /projects/1
   # DELETE /projects/1.xml
   def destroy...
   end
 end

- もし、あなたが生成されたコントローラをみるなら、新しいものをそこにはみつけないだろう。
- すなわち、プロジェクトを生成、検索、更新するためのアクションがある。
- コントローラとアクションの両方は、最初のグレースで普通に現れる
- しかし、それらは、HTTP 動詞(?)によって含まれるリクエストURLの関連を表示する、生- 成されたコメントをもっている
- そこにはREST-URLがあり、次のセクションで詳しく見ていく。


**  REST-URLs [#caa203c2]
- REST-URLは、これまでのralisのような controller/action/idの形式ではない
- controller名のあとにIDがくる
 /projects/1
- Actionがないが、それはHTTP Methodできまる
|HTTP  |Verb       |REST-URL|Action|URL without REST       |h
|GET   |/projects/1|show    |GET|/projects/show/1   |
|DELETE|/projects/1|destroy |GET|/projects/destroy/1|
|PUT   |/projects/1|update  |POST|/projects/update/1 |
|POST  |/projects  |create  |POST|/projects/create   |
- URLはPOST以外はみんな同じ。POSTの場合は、新規に作成だから、まだIDが決まっていない
- WebブラウザはDELETEとPUTをサポートしていない
- Railsは、リソースを削除するためのリンクを生成するための特殊なヘルパーを提供します
- POSTリクエストのhiddenフィールドでサーバーでDELETEメソッドに変換される(1.8.3で説明)
- PUTリクエストも同様(1.8.2で説明)


**  REST actions are using respond to [#c6803637]

- REST actionはことなるレスポンスフォーマットで、ことなるクライアントタイプに反応することができる
- Web アプリケーションのための典型的クライアントタイプはもちろんブラウザクライアントであるが、WebサービスクライアントはXMLを予期するし、RSSリーダーはRSSやAtomフォーマットを予期する
- クライアントによってリクエストされた回答フォーマットの生成のための中央のコントロールインスタンスは、respond toメソッドである。
- これは、すでに、scafforldgeneraterによって、CRUDアクションの中に、生成されている。
- 次のコードの断片はshowアクションでのrespond_toの利用例だ
 # GET /projects/1
 # GET /projects/1.xml
 def show
   @project = Project.find(params[:id])
   respond_to do |format|
     format.html # show.rhtml
     format.xml { render :xml => @project.to_xml }
   end
 end
- respond toはフォーマットを特定した指示をともなうブロックを持っている
- 例では、二つのフォーマットを処理している: HTML, XML
- なにも起こらなければshow.rhtmlを使ったHTMLがかえる
- もし、フォーマットがXMLならXMLが返る
- respond_toは「accept」HTTPヘッダのacceptフィールドか、URLの書式(拡張子など)で判定する

** Accept-Field of the HTTP-Header [#u9122088]
- 「curl」コマンドを使うと、HTTPヘッダが簡単に操作できる
- Acceptヘッダにapplication/xmlを指定して、GETしてみる
 curl -H "Accept: application/xml" -i -X GET http://okra.ark-web.jp/~shida/sandbox/restful_rails/projects


** Format specification via the URL [#l65aa792]
- 次のURLでXML表現を要求できる
 http://localhost:3000/projects/1.xml

** REST-URLs and Views [#u8683cf6]
- link_toはREST URLに対応しない
- linkとボタンによって、HTTP メソッドとURLを送信できることが重要
- Pathメソッドを呼ぶことでhashが置き換えられる
- controller とactionとproject_idの替わりにproject path(:id) が利用される
 link_to "Show", project_path(project)
 =>
 <a href="/projects/1">Show</a>
- URLがREST URLになっている
- デフォルトではGET
- 「Table 1.2: Standard Path-Methods」にあるように、リソースごとに、Railsは7つの標準的なリンクを生成する
- それぞれのパスメソッドはHTTPメソッドと関連づけられ、linkやボタンをクリックすると、サーバーへ送られるHTTPメソッドであることを意味する
- showとupdateは、GETとPOSTなのでそのまま
- createとdeleteは、hidden フィールドを使った、特殊な方法で取り扱われる必要がある。
- これはブラウザはPUT, DELETEは解釈できないためだ。
|Path-Method         |HTTP verb|Path            |Requested Action|h
|projects_path       |GET      |/projects       |index           |
|project_path(1)     |GET      |/projects/1     |show            |
|new_project_path    |GET      |/projects/new   |new             |
|edit_project_path(1)|GET      |/projects/1;edit|edit            |
|projects_path       |POST     |/projects       |create          |
|project_path(1)     |PUT      |/projects/1     |update          |
|project_path(1)     |DELETE   |/projects/1     |destroy         |
- 表の最初の二つはオッケー
- new_project_pathとedit_project_pathは、REST URLとマッチしない


** New and Edit [#u4b40e7c]
- New-LinkをクリックするとGETでサーバーに送信される
 link_to "New", new_project_path
 =>
 <a href="/projects/new">New</a>
- これはRESTの哲学を壊すか?
- newはCRUDアクションではない。これはリソースを生成するための準備である。
- newフォームは最終的にサブミットされる時、はじめてCRUDのcreateアクションが実行される
- このアクションはnewフォームを表示する時だけ使用される
- edit_project_pathメソッドも同様。CRUDアクションのupdateの準備のために使用される
- editフォームをサブミットされた時に実際のupdateアクションが実行される
- 生成されるhref属性は次のようなもの
 edit_project_pathとnew_project_pathの違いはidが必要かどうか
 link_to "Edit", edit_project_path(project)
 =>
 <a href="/projects/1;edit">Edit</a>
- CRUDではないので、newもeditもURLの中にアクションが入るのは問題ない
- この原則は標準のCRUDではないアクションの名前を開発する時も利用できる


** Path-Methods in forms: Create and Update [#f4203e21]
- RESTアプリケーションでは、form_forやform_tagのURLハッシュは、pathメソッドに置き換えられる
-- newフォームのためにprojects_pathは利用される
-- editフォームのためにproject_path(:id)は利用される

*** The New Form [#n944e779]
- 一般的なPOSTでサーバーに送信される
- IDなしのprojects_pathは/projectsになる
 form_for(:project, :url => projects_path) do |f| ...
 =>
 <form action="/projects" method="post">

** The Edit Form [#tc69c296]
- RESTではupdateは、PUTメソッドでリクエストされる
- でも、PUTもDELETEもWebブラウザではサポートされない
- Railsのソリューションは、form_forの:html_hashオプションで、メソッド指定をする方法だ。

 form_for(:project, :url => project_path(@project),
          :html => { :method => :put }) do |f| ...
 =>
 <form action="/projects/1" method="post">
 <div style="margin:0;padding:0">
 <input name="_method" type="hidden" value="put" />
 </div>

- _methodというhiddenフィールドが生成されている
- ディスパッチャがこの値をみて、updateアクションを呼び出してくれる。

** Destroy [#a7db9e9b]
- showとdeleteではproject_pathを使う
 link_to "Show", project_path(project)
 link_to "Destroy", project_path(project), :method => :delete
- destroyのリンクだけ、:methodアクションがある。
- WebブラウザはDELETEメソッドをサポートしないので、Railsは、次のようなJavaScriptを生成する

 link_to "Destroy", project_path(project), :method => :delete
 =>
 <a href="/projects/1"
 onclick="var f = document.createElement(’form’);
 f.style.display = ’none’; this.parentNode.appendChild(f);
 f.method = ’POST’; f.action = this.href;
 var m = document.createElement(’input’);
 m.setAttribute(’type’, ’hidden’);
 m.setAttribute(’name’, ’_method’);
 m.setAttribute(’value’, ’delete’); f.appendChild(m);f.submit();
 return false;">Destroy</a>
- JavaScriptがフォームを生成して、_methodパラメータつきでPOSTメソッドでsubmitしている。
- Railsのディスパッチャがこのパラメータを解釈してdestroyアクションが呼ばれる。


tag: [[Ruby on Rails>tag/Ruby on Rails]], [[勉強会>tag/勉強会]]


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

アークウェブのサービスやソリューションはこちら