変数を含むパスの定義
Rails 3.2.2 で、パスに含まれる値を変数として扱うルーティングを定義したい時の記述方法について。
以下のサンプルではユーザの管理は User モデルで行い、必ず一意である name という値を持ち、ユーザ毎に Item モデルを操作可能だとします。
まずは routes.rb で次のように定義します。
scope "(:user_name)" do resources :items end
ここで () をつけているのがポイントで、これが存在しない場合正しく動作しません。
この段階で params[:user_name] にパスの値が入るようになるのですが、せっかくなのでどこからでもデータにアクセスできるようにメソッドを定義しておきます。コントローラに以下のように記述します。
# coding: utf-8 class ApplicationController # 中略 helper_method :current_user private def current_user @current_user ||= User.where(["name = ?", params[:user_name]]).first end end
これでコントローラやビューから、現在指定されているユーザが誰なのか判別可能になりました。上の例では ApplicationController に記述しましたが、継承させたいコントローラが限られている場合などは適宜記述してください。
ビューから current_user を呼び出す時は、通常のヘルパメソッドのように記述すれば問題ありません。
<%= current_user.name %>
この状態で http://localhost:3000/bob/items にアクセスすると current_user は users.name = 'bob' なユーザに設定されます。
また、上記の例でデフォルト値を使いたい場合は、ルーティングをさらに変更します。
scope "(:user_name)", :default => {:user_name => "bob"} do resources :items end
これでユーザの指定なしで http://localhost:3000/items にアクセスすると、自動的に http://localhost:3000/bob/items に繋いでくれます。
なお root を定義する時は scope の中で行います。
scope "(:user_name)", :default => {:user_name => "bob"} do root :to => "items#index" resources :items end
これで http://localhost:3000 へのアクセスが http://localhost:3000/bob/items に変換されるようになりました。