ログイン処理をできるはずが、internal server error になってしまう。
エラーログ
> Started POST "/session" for ::1 at 2015-05-20 19:25:08 +0900
> Processing by Staff::SessionsController#create as HTML Parameters:
> {"utf8"=>"✓",
> "authenticity_token"=>"aewfM4fLXMzzudio329EdFoUcx1Y6vgwflK33aF+QijyR/srw1C2aABiPAHfpF8j8gJY3ToCUcz56AijGaGB+Q==",
> "staff_login_form"=>{"email"=>"taro@example.com",
> "password"=>"[FILTERED]"}, "commit"=>"ログイン"} StaffMember Load
> (0.1ms) SELECT "staff_members".* FROM "staff_members" WHERE
> "staff_members"."email_for_index" = ? LIMIT 1 [["email_for_index",
> "taro@example.com"]]
>
> Rendered errors/internal_server_error.html.erb within layouts/staff
> (0.1ms) Rendered staff/shared/_header.html.erb (0.2ms) Rendered
> shared/_footer.html.erb (0.0ms) Completed 500 Internal Server Errorin
> 33ms (Views: 31.8ms | ActiveRecord: 0.1ms)
sessions/new.html.erb
<% @title = 'ログイン' %>
<div id="login-form">
<h1><%= @title %></h1>
<%= form_for @form, url: :staff_session do |f| %>
<div>
<%= f.label :email, 'メールアドレス' %>
<%= f.text_field :email %>
</div>
<div>
<%= f.label :password, 'パスワード' %>
<%= f.password_field :password %>
</div>
<div>
<%= f.submit 'ログイン' %>
</div>
<% end %>
</div>
sessions_controller.erb
class Staff::SessionsController < Staff::Base
def new
if current_staff_member
redirect_to :staff_root
else
@form = Staff::LoginForm.new
render action: 'new'
end
end
def create
@form = Staff::LoginForm.new(params[:staff_login_form])
if @form.email.present?
staff_member = StaffMember.find_by(email_for_index: @form.email.downcase)
end
if Staff::Authenticator.new(staff_member).authenticator(@form.password)
session[:staff_member_id] = staff_member.id
flash.notice = 'ログインしました。'
redirect_to :staff_root
else
render action: 'new'
flash.now.alert = 'メールアドレスまたはパスワードが正しく在りません。'
end
end
def destroy
session.delete(:staff_member_id)
flash.notice = 'ログアウトしました'
redirect_to :staff_root
end
end
controllers/staff/base.rb
class Staff::Base < ApplicationController
private
def current_staff_member
if session[:staff_member_id]
@current_staff_member ||=
StaffMember.find_by(id: session[:staff_member_id])
end
end
helper_method :current_staff_member
end
forms/login_form.rb
class Staff::LoginForm
include ActiveModel::Model
attr_accessor :email, :password
end
services/staff/authenticator.rb
class Staff::Authenticator
def initialize(staff_member)
@staff_member = staff_member
end
def authenticate(raw_password)
@staff_member &&
!@staff_member.suspended? &&
@staff_member.hashed_password &&
@staff_member.start_date <= Date.today &&
(@staff_member.end_date.nil? || @staff_member.end_date > Date.today) &&
BCrypt::Password.new(@staff_member.hashed_password) == raw_password
end
end
models/staff_member.rb
class StaffMember < ActiveRecord::Base
before_validation do
self.email_for_index = email.downcase if email
end
def password=(raw_password)
if raw_password.kind_of?(String)
self.hashed_password = BCrypt::Password.create(raw_password)
elsif raw_password.nil?
self.hashed_password = nil
end
end
end
config/routes.rb
Rails.application.routes.draw do
namespace :staff, path: '' do
root 'top#index'
get 'login' => 'sessions#new', as: :login
post 'session' => 'sessions#create', as: :session
delete 'session' => 'sessions#destroy'
end
end