konchanxxx / menta

MENTAのタスク管理用リポジトリ
0 stars 0 forks source link

Ruby on Rails チュートリアル 第8章 #66

Open aoasu05 opened 5 years ago

aoasu05 commented 5 years ago

概要

Ruby on Railsチュートリアルの第8章を勉強しています。 cookiesを使用して、セッションを実装する方法を学んでいます。 初歩的な質問となり、申し訳ありませんが セッションを実装するにあたり理解できない点があったので教えていただければと思います。

実現したいこと

曖昧な点を解消し、理解を深めたいです。 理解できている点 ・セッションはUserモデルとは異なり、cookiesを保存場所とするのでSessionモデルは作成しない ・Sessionモデルを作成しないので、 ActiveRecordのメソッドを使用することができない ・SessionコントローラからUserモデルにアクセスすることはできる  →UserモデルはActiveRecordのメソッドを使用することができるので以下のコードを記述できる

  def create   user = User.find_by(email: params[:session][:email].downcase)   if user && user.authenticate(params[:session][:password])   # ユーザーログイン後にユーザー情報のページにリダイレクトする   else   # エラーメッセージを作成する   render 'new'   end  end

困っていること

以下について理解できていません。 ・インスタンス変数はモデルを作成していないと設定することができない?  →Userモデルにアクセスすることはできるが、Session自体はモデルがないのでインスタンス変数を設定できない? ・createメソッドでユーザ情報の検索結果が失敗した時にエラーメッセージを作成することになっており  ここではflashを記述するように指定している。  ユーザ情報を検索するためにUserモデルにアクセスしたように  エラーメッセージもUserモデルのエラーメッセージを使用することがなぜできないのか?  なぜuser.errors.full_messagesをcreateメソッドで使用できないのか?  これはインスタンス変数を持つことができないから。。。? ・インスタンス変数についてもっと理解が深められるような参考ページがありましたら教えてください。  →分かっていること:コントローラで設定したインスタンス変数はビューでも使用することができる           :同じクラスであれば、インスタンス変数はその他のインスタンスメソッドでも使用できる

konchanxxx commented 5 years ago

・インスタンス変数はモデルを作成していないと設定することができない?

そうです。正しくはモデルというよりはクラスから作成したインスタンスにひもづく変数のためインスタンス変数と呼ばれます。クラスが元になってインスタンスをnewメソッドで作成するのでインスタンスがないとインスタンス変数は使えないです。 https://uxmilk.jp/24330

・createメソッドでユーザ情報の検索結果が失敗した時にエラーメッセージを作成することになっており  ここではflashを記述するように指定している。  ユーザ情報を検索するためにUserモデルにアクセスしたように  エラーメッセージもUserモデルのエラーメッセージを使用することがなぜできないのか?

エラーメッセージを使用しても良いですがflashの方が簡単に設定できるのとモデルに紐づかないエラーメッセージを出すのに使ったりします。 例えば

(1) 入力をやり直してください => モデルに紐づかずエラーメッセージを出力している (2) nameが間違っています => Userモデルとかのnameの値が間違っているというモデルに紐づいたエラーを出している

モデルに紐づいたエラーを出力するときはfull_messagesでそれ以外のメッセージなどを扱うときはflashを使ったりしますね:smile:

konchanxxx commented 5 years ago

@asuka001

aoasu05 commented 5 years ago

ご回答、及び参考URLを添付いただきありがとうございます。 Rubyにおけるインスタンス変数の考え方は分かったのですが それがRailsで実装するとなると途端に混乱してしまいます。 今回のSessionコントローラではなぜインスタンス変数を使用することができないかと言うと Sessionコントローラと言うクラスからインスタンスを作成しないから、インスタンス変数が使えないと言うことでしょうか? Userコントローラではインスタンス変数を使用していたのですが、これはUserコントローラと言うクラスからインスタンスを作成するからインスタンス変数を定義することができていた?このUserコントローラはどこでインスタンスを作成しているのでしょうか? 初歩的な質問で申し訳ありませんが、ご回答いただけると幸いです。

エラーメッセージについては理解できました! ありがとうございます。

konchanxxx commented 5 years ago

遅くなりました!:bow:

今回のSessionコントローラではなぜインスタンス変数を使用することができないかと言うと Sessionコントローラと言うクラスからインスタンスを作成しないから、インスタンス変数が使えないと言うことでしょうか?

Sessionというクラスがないとそのインスタンスを作成することはできないですね

sessionについてはこれが詳しいかもです Rails の session を完全に理解した - Qiita

Userコントローラではインスタンス変数を使用していたのですが、これはUserコントローラと言うクラスからインスタンスを作成するからインスタンス変数を定義することができていた?このUserコントローラはどこでインスタンスを作成しているのでしょうか?

ですです。継承元のActionControllerというRailsのmoduleの中で処理していると思います:bow: 詳細に読み込んだわけではないですが、こことかでやっていますmm rails/renderer.rb at master · rails/rails · GitHub

aoasu05 commented 5 years ago

ご回答ありがとうございます! Userコントロールでは@userなどインスタンス変数を使用しているのに Sessionコントローラではなぜインスタンス変数ではなく、ローカル変数を使用しているのかが分からず RailsチュートリアルではそれはSessionモデルがないからという風な記載がありましたので このような質問をさせていただきました。 いただいた参考URLで理解を深めようと思います! また、確認したいことありましたら質問させていただければと思います。 よろしくお願いします。

konchanxxx commented 5 years ago

Sessionコントローラではなぜインスタンス変数ではなく、ローカル変数を使用しているのかが分からず

これは記事にもありますが実体としてはローカル変数ではなくメソッドかもですね

RailsチュートリアルではそれはSessionモデルがないからという風な記載がありましたので このような質問をさせていただきました。

これって8章のどこらへんの記述でしょうか?

konchanxxx commented 5 years ago

@asuka001

aoasu05 commented 5 years ago

返信遅くなりまして、申し訳ありません。 上記質問の箇所はRailsチュートリアルの8.1.2 ログインフォームの図8.2の下の方に記載があります。

konchanxxx commented 5 years ago

https://railstutorial.jp/chapters/basic_login?version=5.1#sec-login_form

konchanxxx commented 5 years ago

セッションフォームとユーザー登録フォームの最大の違いは、セッションにはSessionモデルというものがなく、そのため@userのようなインスタンス変数に相当するものもない点です。したがって、新しいセッションフォームを作成するときには、form_forヘルパーに追加の情報を独自に渡さなければなりません。

ここでいうセッションフォームはログインフォームのことですね。ユーザー登録の時はユーザー登録処理でUserモデルのインスタンス@userを生成して保存することで新規ユーザーを作成するという流れだったのですが、ログインだと新規に作成するデータがないのでform_forヘルパーに設定するインスタンス変数がないという意味だと思います。 違いは以下のような感じです。

ユーザー登録

form_for(@user) で ユーザーをcreateするためのフォームを生成できた

ログイン

form_for(???) ログインで生成したりするインスタンス(データ)が存在しないのでログインフォームを設定するために form_for(:session, url: login_path) とか情報を設定しないといけない

form_forは便利なヘルパーメソッドでリソース(@userとか)を渡すだけでフォームを生成してくれるのですがフォームに紐づけるリソースが存在しない場合は個別にフォームを作るためのパラメータを設定しないといけないということをここでは言っていると思います。 ちょっと記述が分かりにくいですけど🤔

konchanxxx commented 5 years ago

@asuka001 ご確認をお願いします:bow: