acts_as_authenticatedの使い方 - その3
前回はautheticated_mailerによって生成されるActionMailerの設定が完成したが、authenticated_mailerは、ユーザ登録時に、ユーザが登録したemailアドレスにメールを送信し、そのメールを参照したユーザが記載されているURLにアクセスして初めてユーザ登録を完了するプロセスになる。これを実現するためには、前々回のauthenticatedジェネレータが生成したusersテーブルにactivation_codeとactivated_atという2つのカラムを追加する必要がある。
class AddActivationToUserTable < ActiveRecord::Migration def self.up add_column :users, :activation_code, :string, :limit => 40 add_column :users, :activated_at, :datetime end def self.down remove_column :users, :activation_code remove_column :users, :activated_at end end
上記のコードをdb/migrate/002_add_activation_to_user_table.rbという名前で保存し、rake db:migrateを実行する。
app/models/user_notifier.rbでは、前回ActionMailのテストのためにsignup_notificationメソッドの一部をzzzzzという仮コードに変更してあった。これは上のようにactivation_codeというカラムがテーブルに追加されたので元の状態に戻す。
# @body[:url] = "http://localhost:3000/account/activate/zzzzzzzzzz" @body[:url] = "http://localhost:3000/account/activate/#{user.activation_code}"
ユーザアクティベーション用のコードをmodels/user.rbに追加する。
以下のコードをUserクラス定義の最初の部分、たとえばbefore_save :encrypted_passwdの次に追加する。
# User Activation before_create :make_activation_code
続けて、以下のコードを既存のself.authenticationメソッドの定義と入れ換える。
# Authenticates a user by their login name and unencrypted password. Returns the user or nil. def self.authenticate(login, password) # User Activation - hide records with a nil activated_at u = find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login] u && u.authenticated?(password) ? u : nil end
新規で追加となるメソッドは以下の通り。
# User Activation - Activates the user in the database. def activate @activated = true update_attributes(:activated_at => Time.now.utc, :activation_code => nil) end # User Activation - Returns true if the user has just been activated. def recently_activated? @activated end
最後部のprotectedメソッドにも1つメソッドを新規で追加する。
# User Activation def make_activation_code self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join ) end
次にapp/controllers/account_controller.rbを修正する。
まず、既存のsignupメソッドを以下のコードと置き換える。
# User Activation - need replace signup def signup @user = User.new(params[:user]) return unless request.post? @user.save! redirect_to(:action => 'signup_notification') flash[:notice] = "Thanks for signing up! Please check you mail box." rescue ActiveRecord::RecordInvalid render :action => 'signup' end
そして以下のactivateメソッドを追加する。
# User Activation def activate @user = User.find_by_activation_code(params[:id]) if @user and @user.activate self.current_user = @user flash[:notice] = "Your account has been activated." else flash[:notice] = "Invalid activation code." end end
app/views/accountでは、以下の内容で2つのビューテンプレートを作成しておく。1つが、activate.rhtmlで、もう1つがsignup_notification.rhtmlとする。flashのメッセージを表示する簡単なもので、2つのファイルとも内容は同じでよい。
<%= flash[:notice] %>
これでacts_as_authenticatedおよびメールによるユーザ認証コードの設定は一通り完了となる。localhost:3000/accountにアクセスし、ユーザを登録すると、指定したメールアドレスに確認用メールが配信されること、そこに記載されたURLにアクセスするとユーザ登録が完了することを確認してほしい。