Hatena::ブログ(Diary)

130単位

2011-06-25

Rails3 失敗から学ぶDevise利用時のURL設計

要件

  • ユーザー登録のあるアプリ
  • メアドで仮登録→本登録で各情報入力
    • 仮登録状態の時は本登録に強制遷移
  • 新規登録とは別にマイページが存在
  • ユーザーのプロフィール入力とアプリ設定入力は別画面
  • 新規登録では確認画面や完了画面もほしい
    • マイページでの編集時はなしにした

やや複雑な仕様のため一般化するのは難しいかもしれませんが、自分が選択したやり方を紹介してみます。

環境

  • Rails3.0.7
  • Devise1.3.4

モデル設計

  • User
    • UserProfile
    • UserSetting
  • UserはDevise用フィールドのみにして、プロフィール等は関連モデルで定義

当初のURL設計(失敗例)

#新規登録
match 'register/profile'
match 'register/setting'
post  'register/confirm'
post  'register/create'
get   'register/complete'

#マイページ
get   'my' => 'my#index', :as => :my_root
get   'my/profile_edit'
post  'my/profile_update'
get   'my/setting_edit'
post  'my/setting_update'

#Devise 認証系
devise_for :users, :controllers => { :registrations => 'users/registrations' }, :skip => [ :registrations ] do
  get   'users/sign_up' => 'users/registrations#new', :as => :new_user_registration
  post  'users' => 'users/registrations#create', :as => :user_registration
  put   'users' => 'users/registrations#update', :as => nil
  delete  'users' => 'users/registrations#destroy', :as => nil
  get   'users/sign_up_complete' => 'users/registrations#sign_up_complete', :as => :complete_user_registration
  get   'my/authentication_edit' => 'users/registrations#edit', :as => :edit_user_registration
end
  • ユースケース(URL上の文字列)を第一優先してみた
    • 新規登録とマイページを明確に分けるため
  • Deviseの持つURLとの相性が悪い
    • 認証系のURLは'users'を利用していて統一感がない
  • 仮登録時や更新時のリダイレクト先変更のために自前Controllerを設ける必要がでてきた
  • Devise管理下であるメアド変更画面をマイページで扱おうとした
    • my/authentication_editという苦し紛れなURLになった
    • 'my'に変更するためにわざわざskipしてマッピングし直しているのが微妙すぎる

改良したURL設計

#新規登録
match 'user_entry/profile'
match 'user_entry/setting'
post  'user_entry/confirm'
post  'user_entry/create'
get   'user_entry/complete'

#マイページ
get   'user' => 'user#index'
get   'user/profile_edit'
post  'user/profile_update'
get   'user/setting_edit'
post  'user/setting_update'

#Devise 認証系
devise_for :users, :path => 'user', :controllers => {
  :confirmations => 'user/confirmations',
  :passwords => 'user/passwords',
  :registrations => 'user/registrations',
  :sessions => 'user/sessions',
  :unlocks => 'user/unlocks',
} do
  get   'user/sign_up_complete' => 'user/registrations#sign_up_complete', :as => :complete_user_registration
end
  • リソースを第一優先してRESTfulっぽくしてみた
  • 他ページとの兼ね合いで'user'は単数形にした
  • Deviseの認証系画面とマイページの画面がともに'user'になったことですっきりした
  • 新規登録のほうは名詞でuserと、Deviseの'registration'と区別するために'entry'という単語を用いた
    • Controllerを分けたのは、仮登録状態の強制遷移をController名で簡略化したかったため
  • 前述の通り完了画面遷移の実現は継承した自前Controllerにする必要がある
  • Viewのディレクトリがdeviseとuserで分かれるのを避けるため、中身空のものも含め全て自前Controllerに継承させた
  • Controllerの構成
    • user/*_controller … Devise 認証系
    • user_controller …マイページ
    • user_entry_controller … 新規登録

まとめ

  • Devise利用時、マイページとかのURLはusers(user)にするといいと思う
  • 再編集できるなら確認画面はいらない
  • Railsの流儀に乗っかると開発がスムーズ

【追記】resourceを使ったコンパクトなルーティングの書き方をコメントいただきました。感謝!

4774146633
Ruby on Rails 3 アプリケーションプログラミング

関連記事

tkawatkawa 2011/06/25 14:27 DeviseのURLを"user"にするのは僕もそうしていて、いいと思います。全部統一してしまえば"my"もアリだと思います。
新規登録とマイページの部分は、resourceを使って

resource :user, :only => :show do
resource :profile, :except => [:show, :destroy]
resource :setting, :except => [:show, :destroy]
end

と単純に書けそうです。確認画面や完了画面の調整は必要ですがURLを割り当てなくても作れます。

deeekideeeki 2011/06/25 15:42 確かにその書き方のほうがリソース中心に最適化されていて美しいですね。
新規登録を別Controllerにしたのは、仮登録状態の場合は新規登録画面に飛ばすのを
Controller名で判断しつつ処理したいという意図がありました(もっとうまい方法があるかもしれませんが)。
確認画面の存在は頭を悩ませたところだったりしたのですが、
開発前にうまくディレクターと調整してよりRailsっぽい設計にできるといいのかなと思います。
コメントどうもありがとうございます!

HashHash 2011/08/26 09:48 こういった実例は非常に参考になります。ありがとうございます

deeekideeeki 2011/08/26 12:47 要件がややこしいため今読み返してみても伝わってるのか不安だったりしますが、ご参考になったのでしたら幸いです!

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/deeeki/20110625/rails3_devise_url_structure