ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

いや、べつにTwitterの真似事がしたいわけではないんですけれど

今度は「ログインするときにTwitterみたいにユーザー名とメールアドレス両方受け付けたいよね」みたいな話が持ち上がったので対応してみたいと思います。
ちょうどDeviseのWikiにやりかたが載っていたので、この通りやってみたいと思います。
大体の流れは、

  1. usernameというカラムを作る
  2. ユーザーのモデルにloginというプロパティを作る
  3. Deviseに「login」を認証に使うことを教えてあげる
  4. User.find_first_by_auth_conditionsをオーバーライドする
  5. フォームの入力欄を書き換える

といった感じです。
とりあえず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>

を追加したらできあがりです。ログインできたらおつかれさまでした。
あとはついでに日本語化したりちょっとレイアウトをいじったりすればいいんじゃないですかね、というかんじです。