チワワかわいいブログ

RUNTEQでrails勉強する日々の記録

2020/12/16 railsチュートリアル9章後半、10章

9章残り
remember meをレイアウトに追加

チェックボックス
 <%= f.label :remember_me, class: "checkbox inline" do %>
    <%= f.check_box :remember_me %>
    <span>Remember me on this computer</span>
<% end %>

ログインフォームにチェックボックスを追加。
paramas[:session][:remember_me]に、チェックしてたら文字列の'1'、チェックしていなければ'0'が入る。

if params[:session][:remember_me] == '1'
  remember(user)
else
  forget(user)
end

三項演算子で書くと

params[:session][:remember_me] == '1' ? remember(user) : forget(user)


10章

ユーザーを更新する
<%= form_with(model: @user, local: true) do |f| %>

ユーザー登録時と全く同じコードだがどうやってupdateアクション(PATCH)と認識しているのか
"@user.new_record?がtrueのときにはPOSTを、falseのときにはPATCHを使います。"
とのこと。
htmlを見ると、

...method="post"...value="patch"

とふたつのリクエストの種類がある
今はブラウザではgetかpostしか実装していない(このリクエストしか送れない)
そこでrailsがPATCHリクエストに偽装している。

ユーザーの編集
def update
    @user = User.find(params[:id])
    if @user.update(user_params) #updateでえいや
    else
      render 'edit'
    end
end

@user.updateはupdate_attributeみたいなものか
render 'edit'をする頃には、updateアクションを行ったので@users.errorsにデータが入っているので、renderしたときにエラ〜メッセージが出てくる

allow_nil

現時点ではvalidationでパスワード入ってないとエラーになるが、updateのする時には入力されていない可能性もあるので、 変更する

validates :password, presence: true, length: { minimum: 6 }, allow_nil: true

has_secure_passwordで別にvalidationがあるので未入力のまま作成されることは避けられる。

認可

正しいユーザーだけがアクセスできるようにする。
まず、ログインしてなかったらログイン促すようにする。
"before_action" => リクエストがきたらactionを実行前に行うアクションを指定する

before_action :logged_in_user, only: [:edit, :update]

ログインしてるかをチェック

before_action :correct_user,   only: [:edit, :update]

正しいユーザーかチェック
before_actionを2つに分けているのは、まずログインしていないと、ユーザーが正しいか確認することができないため。
複数ある場合は上から順番に実行する。

def correct_user
  @user = User.find(params[:id])  #アクセスしようとしているページのIDで検索した@userは
  redirect_to(root_url) unless @user == current_user  #current_userと一致しているか
end

リファクタリングすると、

# ヘルパーメソッド定義して
def current_user?(user)
    user && user == current_user #渡されたユーザーがnilではなく、current_userと一致すればtrueを返す
end

def correct_user
   @user = User.find(params[:id]) #アクセスしようとしているページのIDで検索した@user
   redirect_to(root_url) unless current_user?(@user) #@userがnilではなく、current_userと一致しなければ
end
フレンドリーフォワーディング

ログインした後にもともと行きたかったとこにリダイレクトしてあげる

# 記憶したURL(もしくはデフォルト値)にリダイレクト
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default) #リクエストしたページがあればそちら、なければデフォルト
    session.delete(:forwarding_url)
  end

  # アクセスしようとしたURLを覚えておく
  def store_location
    session[:forwarding_url] = request.original_url if request.get?  #session変数に:forwading_urlをキーとしてリクエストしたURLを保存
  end

before_action :logged_in_userの中に、store_locationメソッドを入れることで、ログインしていない人が行きたかったURLを保存(した上で、ログインページにリダイレクトする)
ログインするとき(セッションを作成する時)に、session[:fowarding_url]が存在すればそこにリダイレクトして欲しいので、session controllerのcreateアクションのリダイレクトを変更する

request.get?

このコードでフォームから送ったリクエストがgetリクエストかどうかを確認している。
before_actionで制限している2つのうち、patchリクエスト(update)ではなくgetリクエスト(edit)の時だけ保存できたらいい。