ほとんどこの記事の要約です。
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
オブジェクトと共にインスタンス化されるので、matches?
メソッドの中でsession
を触ることもできます1。
実装例は下記の通りです。
config/routes.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のメンバー名を指定してサブクラスを作る機能を使って実装されていました。これ便利。
app/constraints/logged_in_constraint.rb2
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/