いや、べつにTwitterの真似事がしたいわけではないんですけれど
今度は「ログインするときにTwitterみたいにユーザー名とメールアドレス両方受け付けたいよね」みたいな話が持ち上がったので対応してみたいと思います。
ちょうどDeviseのWikiにやりかたが載っていたので、この通りやってみたいと思います。
大体の流れは、
- usernameというカラムを作る
- ユーザーのモデルにloginというプロパティを作る
- Deviseに「login」を認証に使うことを教えてあげる
- User.find_first_by_auth_conditionsをオーバーライドする
- フォームの入力欄を書き換える
といった感じです。
とりあえずlogin-name-or-mailみたいなブランチを切ってから作業を始めましょうか。
まずは
rails generate migration add_username_to_users username:string:uniq
でマイグレーションファイルを自動生成してから、
rake db:migrate
でマイグレーションします。それから、ユーザーのモデルの方にも
attr_accessible :username
と追加しておきます。ここまでは簡単ですね。
次に、
attr_accessor :login attr_accessible :login
とやって、loginというプロパティを作ります。
今度はDeviseの設定です。
config/initializers/devise.rbというファイルに以下の設定を書き足します。
config.authentication_keys = [ :login ]
もしくはユーザーのモデルに
devise :authentication_keys => [:login], #以下省略
と書き足してやっても構いません。
終わったら、User.find_by_first_by_auth_conditionsを以下のようにオーバーライドします。
def self.find_first_by_auth_conditions(warden_conditions) conditions = warden_conditions.dup if login = conditions.delete(:login) where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first else where(conditions).first end end
usernameにバリデーションも追加しておきます。
Be sure to add case insensitivity to your validations on
:username
とか言われているのでちゃんと書いておきます。
validates :username, :uniqueness => { :case_sensitive => false }, #以下省略
最後に、ビューを書き換えます。app/views/deviseというディレクトリがある方はすでに打ち込んでいる気がするので必要ありませんが、ない方は
rails g deviese:views
と打ち込んでビューのファイルを作りましょう。
ログインフォームのメールアドレスを入力するところを
<!-- app.views/devise/sessions/new.html.erb --> <!-- #編集前 --> <p><%= f.label :email %><br /> <%= f.email_field :email %></p> <!-- 編集後 --> <p><%= f.label :login %><br /> <%= f.text_field :login %></p>
と編集し、
ユーザー情報を編集するページと登録するページのフォームにそれぞれ、
<!-- app/views/devise/registrations/edit.html.erb および edit.html.erb --> <p><%= f.label :username %><br /> <%= f.text_field :username %></p>
を追加したらできあがりです。ログインできたらおつかれさまでした。
あとはついでに日本語化したりちょっとレイアウトをいじったりすればいいんじゃないですかね、というかんじです。