deviseのユーザー情報編集でcurrent_user.updateという記述にハマる

今わかっていることをまとめておく。

この件は、教材の流れには直接関係ないし、エラーが出て詰まったわけでもない。
結果だけ先に書くと、結局何が正しいのかもまだちゃんとわかっていない。
でもすごく気になって、ここ数日ずっと考えたり調べたりしていたので
とりあえず今のところ理解したことを書いておく。
未来の自分がこの疑問をスッキリ解決してくれるといいのだけど…

deviseでユーザー情報更新機能を実装する

deviseのユーザー管理機能実装の教材で、ユーザー情報更新機能を作りましょうとなったとき。自分の頭の中ではなんとなく

①DBから今ログインしているユーザー情報を持ってくる
 (Users#newアクションで)
②それを表示させたユーザー情報編集画面を作る
 (views/users/edit.html./erb)
③DBから今ログインしているユーザー情報を持ってきて、
 編集画面のフォームから流れてきた情報を上書きしてupdateし、トップページにリダイレクトする。
 (Usesr#updateアクションで)

という流れを想像した。そこで、
とりあえず③のupdateアクションに関して以下のように記載。
(※後でわかったんですが以下の記述は.valid?の使い方が変でした。汗
今回はここかメインの話じゃないので詳細は記載しません)

  def update
    user = User.find_by(params[:id])
    user.update(user_params)
    if current_user.valid?
       redirect_to root_path
    else
      render :edit
    end

#中略

  private
  def user_params
    params.require(:user).permit(:name, :email)
  end


editのビューファイルは内容記述済の用意されていたものを
教材に言われるがままディレクトリにポンと入れただけなので、
この話は一旦おいておく。

上記のコードは一応想定通りの動きはしてくれた。
(教材で実装中のアプリのためスクショは載せられないが…)

ただ、教材の記載としては以下のような感じだった。
(そのまま載せられないので一部変えた。)

def update
    if current_user.update(user_params)
      redirect_to root_path
    else
      render :edit
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end


「current_user.update」??

最初にこの記載を見たとき、全然ピンとこなかった。
「current_userって今ログインしているユーザーの情報が入っていて、
それにupdateをかける…???」っていう状態。
なんかたぶん、自分の中でcurrent_userの機能ってログインした瞬間とかにユーザー情報が入って、ログアウトしたらそれが消えるみたいな、
セッションみたいなもの?を想像していたからかもしれない。
current_userっていう変数に、ユーザー情報を格納している的なイメージだった。

current_userって一体何なのか?

まずそもそもそれを全然理解していなかった。
以下参考にさせていただきました。
tech.mof-mof.co.jp

def current_#{mapping}
 @current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
end

current_userはdeviseのヘルパーメソッドで、Userモデルのインスタンスが戻り値になるらしい。
インスタンスだったのか。
上記がこのメソッドの中身だが、認証してDBにアクセスしてデータを持ってきている?みたいな動きなんだろうか。


それであれば、自分がやりたかったことが

今のユーザー情報をDBから持ってくる
   ↓
フォームの送信してきた内容で上書きする
   ↓
その内容をDBに保存する

なので、教材の見本通りにcurrent_user.updateはやっていることは同じだし、こっちのほうが短い&ひと目でわかりやすいコードだと思うのだが…

気になる記事

"current_user.update"でググると一番上に出てくるこちら。
diary.shu-cream.net
この件で調べ始めて一番最初に出会った記事。

フォームで変更するオブジェクトが、フォーム以外の場所でも表示されている場合、フォームで変更するオブジェクトと表示するオブジェクトは分けておかないと意図していない挙動になるから注意しましょう。

とのこと。なるほど。
一応自分で、views/users/edit.html./erbにcurrent_userを表示させるようにして
更新後のリダイレクト先を編集ページのままにしたりしていろいろ試したが、
current_userの中身を不正な状態にはできていなさそうで再現はできなかった。

それと、そもそもこの「current_user.update」というソースコード自体が
あまり検索に引っかからないような感じがして、
実はもっといい感じの書き方があるのだろうか、とかそもそもdeviseのユーザー編集ってそんなに話題にならないのかなとか(パスワードなしで編集する、ための記事はたくさんあった)いろんなことを考えてしまった。


でもこれのせいで教材の進みもだいぶ鈍足になったし復習する時間もほしいのにこれの検索ばっか何時間もしてるしでここ数日とにかく効率が悪かった。
まだrubyrails初めて3週間とかだし、いろんなことに興味があったり疑問を持つのも大事だろうけど
まずはしっかり教材進めて慣れていくためにもある程度割り切ってガンガン進めなきゃってすごく思う。
でも気になると延々調べてしまう。今みたいなベース知識が無の状態であちこち調べ回っても納得できる答えに出会えないのは理解しているんだけど。


性分だなあ。
それがいい時に働くときもあるだろうけど、今は変えたほうがいい性分だと思う。