RailsTutorial8章
積読中
全体像
メソッドについて
user = User.find_by(email: params[:session][:email].downcase) if @user && @user.authenticate(params[:session][:password])
if@userがないと一行目でnilが返って来たときにnilに対してauthenticate を使うことになってerrorが出ることを防ぐ目的がある。
renderとredirect_toの違い
参考 【Rails】renderとredirect_toの違いと使い分け - Qiita
DB問い合わせ削減の書き方
def current_user if session[:user_id] @current_user ||= User.find_by(id: session[:user_id]) end end
if session[:user_id]と予め書いておくことでfind_byの試行回数を減らせる。 DB問い合わせ数削減のため。
@current_userがnilまたはfalseだったら右を実行する。 これもDBへの問い合わせ削減。インスタンス変数の寿命の長さを利用したコ−ド。
なぜsessions_controllerではインスタンス変数ではなくローカル変数を使うのか
Ruby - railsチュートリアル 8章 createアクション内の変数についての質問|teratail
def login(user)の理由について
def log_in(user) session[:user_id] = user.id end
log_in(user)とuserを引数にとらないようにするため 以下のように書けるが
session[:user_id] = @user.id
一般的に Helper は参照透過性のある関数として書かれることが良いとされるため 別の Controller からも log_in ヘルパーを利用したくなった時に、「log_in ヘルパーを呼ぶ前に予め @user というインスタンス変数にログインしたいユーザーのインスタンスをセットしておくこと」 という複雑なルールを強いられることになります。それよりも、単純に log_in のシグネチャーとして「引数で渡されたユーザーでログインする」という挙動にしておいた方がシンプルなので設計として 落ち着きやすいわけです。
application_helperとapplication_controllerに書くときの違いについて
application_helper
viewをDRYにするためのもの
application_controller
共通のメソッドをまとめるためのもの
session_helper
module SessionsHelper def log_in(user) session[:user_id] = user.id end def current_user if session[:user_id] @current_user ||= User.find_by(id: session[:user_id]) end end def logged_in? !current_user.nil? end def log_out session.delete(:user_id) @current_user = nil end end
sessions_controller.rb
class SessionsController < ApplicationController def new end def create user = User.find_by(email: params[:session][:email].downcase) if @user && @user.authenticate(params[:session][:password]) log_in user redirect_to user else flash.now[:danger] = 'Invalid email/password combination' # 本当は正しくない render 'new' end end def destroy log_out redirect_to root_url end end
application_controller
class ApplicationController < ActionController::Base include SessionsHelper end
users_controller
class UsersController < ApplicationController def show @user=User.find(params[:id]) end def new @user = User.new end def create @user = User.new(user_params) if @user.save log_in @user flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end