1. fujimura

    No comment

    fujimura
Changes in body
Source | HTML | Preview
@@ -1,53 +1,56 @@
ほとんどこの記事の要約です。
User-centric Routing in Rails 3 // Collective Idea | Crafting web and mobile software based in Holland, Michigan
http://collectiveidea.com/blog/archives/2011/05/31/user-centric-routing-in-rails-3/
例えばアプリケーションのルート(e.g. `http://example.com`) で、ログイン時はマイページ、非ログイン時はランディングページを表示したい。そういう時はどうすればいいでしょうか。
ビュー内で分岐、コントローラーでビューを出し分ける、同じパスで出すことを諦める、などの解決策がありますが、もうちょっと賢い方法がありました。
Railsでは、特定の条件を満たした時のみルーティングを行う、ということができます。`id`が期待される部分は数字のみ、というように正規表現を使ったりする場合がよくあるパターンだと思いますが、これ、実は`#matches?`というメソッドを実装したクラスを渡すことで制限をかけることもできます。この機能を使って、`/`にアクセスした時、`current_user`のセッションがある時は`MyPageController#index`、ない時は`LandingPageController#index`にルーティングする、ということが可能です。
渡されたクラスは[`request`](http://api.rubyonrails.org/classes/ActionDispatch/Request.html)オブジェクトと共にインスタンス化されるので、`matches?`メソッドの中で`session`を触ることもできます[^request]。
[^request]: `#session`メソッドは`Rack::Request`に実装されていて、`ActionDispatch::Request`は`Rack::Request`を継承している
実装例は下記の通りです。
config/routes.rb
```rb
Rails.application.routes.draw do
# 前略
# セッションがない時
# Rails 4では`as` を使って別名を当てる必要があります。Rails 3では不要かも(試してません)
root 'public#index', as: :public_root, constraints: LoggedInConstraint.new(false)
# セッションがある時
root 'home#index', constraints: LoggedInConstraint.new(true)
# 後略
end
```
条件判定用のオブジェクトは何でもいいのですが、[Structのメンバー名を指定してサブクラスを作る機能](http://docs.ruby-lang.org/ja/2.3.0/method/Struct/s/=5b=5d.html)を使って実装されていました。これ便利。
app/constraints/logged_in_constraint.rb[^constraint]
[^constraint]: 場所は別に`/app/constraints`でなくても大丈夫です。
```rb
class LoggedInConstraint < Struct.new(:value)
def matches?(request)
request.session.key?('current_user_id') == value
end
end
```
+追記:
+こっちのほうが簡単だった!
+http://qiita.com/sue738/items/976c8abf4aa8e530899f
参考URL
- Rails Routing from the Outside In — Ruby on Rails Guides http://guides.rubyonrails.org/routing.html#advanced-constraints
- User-centric Routing in Rails 3 // Collective Idea | Crafting web and mobile software based in Holland, Michigan
http://collectiveidea.com/blog/archives/2011/05/31/user-centric-routing-in-rails-3/