理解しずらかったので、テスト以外の追加コードをまとめた。
もう一周するとき、もっと深ぼりする。
実際には、テストもやっています。
追記変更 #
#Remember me 機能
app/models/user.rb
attr_accessor :remember_token
def User.new_token #ランダムなトークンを返す
SecureRandom.urlsafe_base64
end
def remember # 永続セッションのためにユーザーをデータベースに記憶する
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
def authenticated?(remember_token) # 渡されたトークンがダイジェストと一致したらtrueを返す
return false if remember_digest.nil? # authenticated?を更新して、ダイジェストが存在しない場合に対応
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
def forget # ユーザーのログイン情報を破棄する
update_attribute(:remember_digest, nil)
end
app/controllers/sessions_controller.rb
.
.
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
remember user # ログインしてユーザーを保持する
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
log_out if logged_in? # ログイン中の場合のみログアウトする
redirect_to root_url
end
app/helpers/sessions_helper.rb
def remember(user)# ユーザーを永続的セッションに記憶する
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
def current_user # 記憶トークンcookieに対応するユーザーを返す
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
def forget(user) # 永続的セッションを破棄する
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
def log_out
forget(current_user) # 現在のユーザーをログアウトする
session.delete(:user_id)
@current_user = nil
end
#[Remember me] チェックボックス
app/views/sessions/new.html.erb
.
.
.
<%= f.label :remember_me, class: "checkbox inline" do %>
<%= f.check_box :remember_me %>
<span>Remember me on this computer</span>
<% end %>
app/controllers/sessions_controller.rb
.
.
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
remember user
params[:session][:remember_me] == '1' ? remember(user) : forget(user) # チェックボックスの送信結果を処理する
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
#テスト重要
空でテスト書くのはまだまだ。
二年前の大学院の授業では、Rubyのコミッターの方が、minitestを押していたので、取り敢えずマスターしたい。
テストで重要なことは、webを使う時に、userがやってしまうことを洗い出すことだとわかった。
良い手法: raiseを使う