Skip to content

浜松rails3道場 routing編

mackato edited this page May 11, 2011 · 39 revisions

浜松Rails3道場とは、習うより慣れろ方式で、Rails3のツボを浜松のRubyist達へ伝える試みである。

Routing編

参考

前準備

練習用のRailsプロジェクトを作る。参考環境: Ruby 1.9.2, Rails 3.0.7

% rails new routing-dojo
% bundle install

Routingとは

HTTPリクエスト(URL、メソッド)を受け取って、コントローラーのアクションを呼び出す仕組み。また、パスやURLを生成し文字列によるこれらのハードコードを回避することができる。

The Rails router recognizes URLs and dispatches them to a controller’s action. It can also generate paths and URLs, avoiding the need to hardcode strings in your views.(Ruby on Rails Guides)

Routingを使う

確認用のコントローラーを生成

rails g controller catalog view

設定ファイルにrouteを追加する。

# config/routes.rb
match 'products/:id' => 'catalog#view'

Viewで使う

<% # app/views/catalog/view.html.erb %>
<%= link_to 'Product: 2', :controller => 'catalog', :action => 'view', :id => 2 %>

Controllerで使う

# app/controllers/catalog_controller.rb
redirect_to :controller => 'catalog', :action => 'view', :id => 3

Routingを確認する

  • サーバーを起動しブラウザで確認
  • rake routes タスクで確認
  • rails console コマンドで確認
  • テストを書いて確認

コンソールで確認

% rake routes
...
/products/:id(.:format)          {:controller=>"catalog", :action=>"view"}
...
% rails console
Loading development environment (Rails 3.0.7)
> r = ActionController::Routing::Routes
> r.recognize_path '/products/1'
 => {:controller=>"catalog", :action=>"view", :id=>"1"}
> r.generate :controller => 'catalog', :action => 'view', :id => '2' 
 => "/products/2"

Routingのテスト

Railsのコントローラーのテストでは、Routingをテストするための3種類のビルトインアサーションが用意されている。

# test/functional/catalog_controller_test.rb

# assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)
assert_generates "/products/1", :controller => 'catalog', :action => 'view', :id => '1'

# assert_recognizes(expected_options, path, extras={}, message=nil)
assert_recognizes({ :controller => "catalog", :action => "view", :id => "2" }, "/products/2")

# assert_routing(path, options, defaults={}, extras={}, message=nil)
assert_routing({ :path => "/products/3", :method => :get },
               { :controller => "catalog", :action => "view", :id => "3" })

url_forなどを使いビューのテストでも検証することができる。

# test/unit/helpers/catalog_helper_test.rb
assert_equal '/products/1', url_for(:controller => 'catalog', :action => 'view', :id => '1')
試してみよう!
  • 'products/:id' の productsと:id の部分を変更してみよう。
  • ビューで :controller や :action などのキーをTypoしてみよう。
参考

Test::Unitの代わりにRSpecを使うと専用のRouting specsが生成される。

# spec/routing/catalog_routing.spec
describe "routing to catalog" do
  it "routes /products/:id to catalog#show for id" do
    { :get => "/products/1" }.should route_to(
      :controller => "catalog",
      :action => "view",
      :id => "1"
    )
  end
end

Named routes

Routeには名前を付けることができる。

# config/routes.rb
match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase

# test/functional/catalog_controller_test.rb
assert_equal "/products/1/purchase", purchase_path(:id => '1')
assert_equal "http://test.host/products/2/purchase", purchase_url(:id => 2)

アプリケーションのrootでは専用のショートカットが使える。

root :to => "welcome#index" # root_path => '/'
試してみよう!
  • 'catalog#view' へのRoutingにも名前を付けてみよう。
  • ビューでxxx_path, xxx_url をTypoしてみよう。

教訓その1

名前なきRoute使うべからず! 名前付きの方がトラブルが少なく、テストもしやすい。

Resource Routing: the Rails Default

Resources on the Web

CRUD, Verbs, and Actions

Paths and URLs

Defining Multiple Resources at the Same Time

Singular Resources

Controller Namespaces and Routing

Nested Resources

Creating Paths and URLs From Objects

Adding More RESTful Actions

Customizing Resourceful Routes

Specifying a Controller to Use

Specifying Constraints

Overriding the Named Helpers

Overriding the new and edit Segments

Prefixing the Named Route Helpers

Restricting the Routes Created

Translated Paths

Overriding the Singular Form

Using :as in Nested Resources

Clone this wiki locally