```

    エラーログ
    
    > 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
    
```
CC BY-SA 3.0
2015-05-20T10:37:42.363
10418
2015-05-20T10:37:42.363
8991
question
ruby-on-rails
ログイン処理をできるはずが、internal server error になってしまう。