はじめに
Rails チュートリアルなどで、Railsの勉強をしていてフォームの実装をしていた時に、ユーザー登録などのフォームと、ログインに使うフォームでコードが違っていたので、何が違うんだろうと調べていたら勉強になったので、まとめておきます。
環境
この記事では以下の環境(2018年6月15日時点)で動作確認できました。
- Ruby: 2.4.1
- Rails: 5.0.7
主な違い
セッションフォームとユーザー登録フォームの主な違いは、セッションにはSession
モデルというものが無いため、例えば、ユーザー登録のフォーム(View
)でよく見る<%= form_for(@user) do |f| %>
で始まるフォームにある@user
のようなインスタンス変数に相当するものが無いことだと思います。それに対して、セッションフォームの場合、form_for
のView
に関するヘルパーにリソースの名前とそれに対応するURLを明示する必要があります。
まず前提として、HTTPはステートレスな通信プロトコルなので、一度の送受信がわかったら(例えばページを遷移したら)、前に持っていた情報(状態(ステート))は失われます。例えばログインに関してだと、これでは困りますよね?だって、ページ遷移するたびにログインしなきゃいけないのですから。Amazonで欲しい商品をカートに入れて違う商品ページに遷移したら、カートに入れた商品がカートから無くなってしまいます。だけど実際はそうなっていないですよね?それは、サーバにセッションという技術が、ブラウザにはクッキーという技術が用いられているからです。
そして、これは推測なのですが、なぜログイン情報をセッションでも持つのかについては、例えばログイン情報やAmazonのカートの中に入っている商品情報は、DBに格納するような永久的に保存する情報では無いからというのと、何度かページ遷移する(アクセス頻度が高い)ことを考えると、いちいちDB保存するのはパフォーマンスが悪いからだと私は考えてます(間違ってたらご指摘ください)。
ユーザー登録のフォーム
ユーザー登録のフォーム(View
)は以下のようになってることが多いと思います。(インスタンス変数名(@user
)は仮)
<%= form_for(@user) do |f| %>
...
<% end %>
@user
は、Controller
のnew
アクションで用意して(と仮定して)フォームを作成することを明示しています。ここで入ったデータが、create
へ送られます。フォームの内容はparams[:user]
に入っていきます。
Rails では、form_for(@user)
と書くと、フォームに入ったデータのアクションは/users
というURLへのPOSTだと、自動的に判定してくれます。しかし、セッションの場合はリソースの名前とそれに対応するURLを指定する必要があります。
セッションフォーム
セッションフォーム(View)は以下のようになってることが多いと思います。
<%= form_for(:session, url: login_path) do |f| %>
...
<% end %>
セッションフォームの場合、form_for
のView
に関するヘルパーにリソースの名前とそれに対応するURLを具体的に指定する必要があります。
- リソース名:
:session
- 対応するURL:
login_path
(POST)
Railsにおけるリソースとは、コントローラが扱う対象に名前をつけたものです。リソースには、モデルや、セッション、画像などがあります。今回は、セッションを扱うよと明示的に宣言したことになります。(実は、名前(今回なら:session
)は、なんでもいいみたいです。ならどうやって、セッションだと判定してるのだろうか。。)
セッションフォームなので、例えば、この後、new
のページから送信されたフォーム(仮にメアドやパスワードの情報があるとする)を処理するcreate
アクションでは
email = params[:session][:email]
password = params[:session][:password]
こんなのが出てくると思います。
params[:session][:email]
これはフォーム(new
)から送信されたメールアドレスです。
params[:session][:password]
これはフォーム(new
)から送信されたパスワードです。
こうすることで、create
アクションでは、ログインに必要な情報をparams
ハッシュから簡単に取り出せます。
以上です!
この記事を読んだ方に
この記事を読んで、誤っている箇所をみつけたり、追記した方がいい内容などありましたら、編集リクエストやコメント欄で指摘していただけると助かります。
参考
- http://railspro.net/questions/1573
- https://railstutorial.jp/chapters/log_in_log_out?version=4.2#cha-8_footnote-ref-3
- http://stonebeach-dakar.hatenablog.com/entry/2016/07/14/222653#%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%A8%E3%81%AF
- https://qiita.com/To_BB/items/dc37877eebd0c45f758a
- https://qiita.com/hththt/items/07136ad74127999df271
- https://qiita.com/7968/items/ce03feb17c8eaa6e4672