BNBのプログラミング勉強記録

ガチのプログラミング初心者が駆け上がっていくブログ

メモ(Rails VIII)

パスワード非表示

<input type="password">

getとpostで同じURLを指定した場合

  • 「/login」で2つのルーティングが被っているように見えるが、「get」と「post」では異なるルーティングとして扱われるので問題なし
  • link_toメソッドではデフォルトでgetのルーティングを探し、form_tagメソッドがデフォルトでpostのルーティングを探す
  get "login" => "users#login_form"
  post "login" => "users#login"

find_byで複数条件

@user=User.find_by(email: params[:email],password: params[:password])

session変数

  • ページを移動してもユーザー情報を保持し続けるために、sessionという特殊な変数を用いる
  • sessionに代入された値は、ブラウザに保存される
  • sessionに値を代入すると、ブラウザはそれ以降のアクセスでsessionの値をRailsに送信する
  • sessionに値を代入するときには、下記のようにuser_idをキーとし、値を代入する
def login
    @user = User.find_by(email: params[:email], password: params[:password])
    if @user
      session[:user_id]=@user.id
#中略
<% if session[:user_id] %>
          <li>
            現在ログインしているユーザーのid:
            <%= session[:user_id] %>
          </li>
        <% end %>

ログアウト

  • ログアウトする、つまり「ログイン状態でなくする」にはsession[:user_id]の値を空にする
  • すなわちsession[:user_id]にnilを代入する
  • データベースを変更するときに加え、 session の値を変更する場合でも post を用いることになっている
<%= link_to("ログアウト", "/logout",{method: "post"})  %>
def logout
    session[:user_id] = nil
    flash[:notice] = "ログアウトしました"
    redirect_to("/login")
  end

before_action

  • 各コントローラの全アクションで共通する処理がある場合には、before_actionを使うと便利
  • before_actionを用いることで、アクションが呼び出される際に必ずbefore_actionの処理が実行される
  • これにより、全アクションで共通する処理を1箇所にまとめることができる
  • 全てのコントローラで共通する処理はapplicationコントローラにまとめることができる。ここでbefore_actionを用いる
class ApplicationController < ActionController::Base

  before_action :set_current_user
  
  def set_current_user
    @current_user = User.find_by(id: session[:user_id])
  end
  
end
<% if @current_user %>
          <li>
            <%= link_to(@current_user.name, "/users/#{@current_user.id}") %>
          </li>
#後略

アクセス制限の処理を共通化

  • applicationコントローラにauthenticate_userというメソッドを作成し、アクセス制限の処理を共通化する
  • 全アクションに適用したい訳ではないので、各コントローラの各アクションでbefore_actionを適用する
  • まずonlyを用いて各コントローラでbefore_actionを使うことで、指定したアクションでのみそのメソッドを実行することができる
  • 各コントローラは、applicationコントローラを継承しているので、継承元のメソッドを使うことができる
  • @current_userがauthenticate_userメソッドの中でも使用されていることに注目。@変数で定義した変数は同じクラスの異なるメソッド間で共通して使用することが可能
  • 分かる、分かるぞ〜。俺でも分かるということは、Railsは相当すごいということ。
def authenticate_user
    if @current_user ==nil
      flash[:notice]="ログインが必要です"
      redirect_to("/login")
    end
  end
class UsersController < ApplicationController
  before_action :authenticate_user,{only: [:index, :show, :edit, :update]}

アクセス制限の処理を共通化 その2

  • 逆にログインしていたら、ログインページとかは見せない、という仕様にする、にはどうすればいいか?という話
  • 実際そうなっとんかなあ。
  • forbid=禁止する
def forbid_login_user
    if @current_user
      flash[:notice] = "すでにログインしています"
      redirect_to("/posts/index")
    end
  end
before_action :forbid_login_user, {only: [:new,:create,:login_form,:login]}

勝手に編集できないようにするには

  • 注意点としては、params[:id]が文字列なのでto_iメソッドにて数値化する必要があるということ
  • ensure=インシュア=保証する
  • なんか、それぞれのアクションに書きゃええのに、と一瞬思ったけど、ビフォーなんちゃらでまとめて指定することに、railsの思想を感じたわ
  • フーン感半端ねえ
before_action :ensure_correct_user, {only: [:edit,:update]}

#中略

def ensure_correct_user

    if @current_user.id!= params[:id].to_i
      flash[:notice]="権限がありません"
      redirect_to("/posts/index")
    end

  end