Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

プラクティス提出:Railsにおけるリクエストからレスポンスまでの流れ説明/curl, Postman, ブラウザを使ってHTTPを理解 #1

Merged
merged 3 commits into from Apr 19, 2021

Conversation

saeyama
Copy link
Owner

@saeyama saeyama commented Apr 11, 2021

下記プラクティスを提出致します。お手すきの時に確認お願い致します。

  • Railsにおけるリクエストからレスポンスまでの流れについて説明してください
  • curl, Postman, ブラウザを使ってHTTPを理解する

- データベース
---

WEBブラウザ上で、`link_to`で指定されている`tasks_path`の `一覧`ボタンを押下するとWEBサーバーにHTTPリクエストが送られる。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link_toって単なるHTMLを出力するメソッドに過ぎないのは理解されてますか?
また、tasks_pathってなんでしょう?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙇‍♀️
はい、一応下記のように認識しております。
link_toaタグを生成するメソッド。
tasks_pathroutes.rbresources :tasksで生成されたルーティングのPrefixtasksにpath指定をしたものでhref属性を指す。tasks_path`はルーティングで言うと、一覧ページのことを指す。

上記は裏側での内容なので…WEBブラウザ上で見た場合、シンプルに下記のように修正するのが良さそう…ですね。

  • 指摘箇所文章修正

WEBブラウザ上で一覧ボタンを押下すると、WEBサーバーにHTTPリクエストが送られる。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tasks_pathはルーティングで言うと、一覧ページのことを指す。

tasks_path/tasksを出力します。
なので<a href="/tasks">が出力されます。
ユーザーはそのリンクをクリックすると/tasks に対してGETリクエストを送ることになります。

という流れは理解されてますか?
tasks_path = 一覧ページのことを指す」のような表現がちょっと気になりました!

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

理解がかなり曖昧になってました!
tasks_path/tasksを出力するというところがちゃんと理解出来てなかったです。

tasks GET    /tasks(.:format)                 tasks#index

上記のroutesを見て単純に一覧ページ(index)と認識してました。

link_to(aタグ生成)にtasks_path(href属性のリンク先である/tasksを出力)を指定することでHTML側で<a href="/tasks">が出力され/tasks に対してGETリクエストを送るって流れですね。
腑に落ちました!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

おぉ良かった!

rails consoleapp.tasks_path と打ってみるといいですね。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

irb(main):001:0> app.tasks_path
=> "/tasks"

めちゃわかりやすいですね!

---

WEBブラウザ上で、`link_to`で指定されている`tasks_path`の `一覧`ボタンを押下するとWEBサーバーにHTTPリクエストが送られる。
一覧ページを表示させるにはHTTPリクエストの`Request URL`に`routes.rb`で設定した一覧ページのエンドポイント`/users `を指定し、`Request Method`には`GET`を指定する。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なんとなく順序が逆な気がします。

/usersに対してGETリクエストを送ると交通整備のおじさんがusers_controller#indexに処理を振り分けて、そのアクションの中でユーザー一覧用のページを生成してクライアントに返す。という流れですがその認識はありますか?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この下の記述をみる限り理解しているみたいですね!

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙇‍♀️

  • ご指摘箇所文章修正

HTTPリクエストはRequest URLroutes.rbで設定した一覧ページのエンドポイント/users に対して、Request MethodGETを指定してWEBサーバ(Railsアプリケーション)にリクエストを送る。

一覧ページが表示される流れとしては、/usersに対してGETリクエストを送るとusers_controller#indexに処理を振り分けられ、そのアクションの中でユーザー一覧用のページを生成してクライアントに返す。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

routes.rbで設定した一覧ページのエンドポイント/users に対して、Request MethodにGETを指定してWEBサーバ(Railsアプリケーション)にリクエストを送る。

間違いではないんですが、僕個人のニュアンスだと、
RESTfulの考えに則ると、ユーザーの一覧を取得したい場合は/users というURLに対して GETのリクエストを投げることでそれを実現する。よって/usersに対してGETが送られた場合のハンドリングをしてあげないといけない。そのためにroutes.rbresources :usersを書いてあげる。

っていう認識なんですよね。
さえこさんの表現だとなんとなくroutes.rbありきで書いてるような気がしちゃったのでちょっと突っ込ませてもらいました!

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

おっしゃる通りroutes.rbありきで考えてました…!あくまでもroutes.rbはURLに対してGETやPOSTのリクエストを投げて、それを実現するための対応方法を記述しているということですね。ハンドリングって言葉で腑に落ちました!

<% end %>
```

WEBブラウザはHTTPレスポンスの`Content-Type: text/html; charset=utf-8`に従い、ユーザーにわかりやすくHTMLをレンダリングする。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines 24 to 27
rails routes

GET /users/new(.:format) users#new
```

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

GET /users/new(.:format) users#new
```

Railsサーバーはリクエストをroutesに送り、routesはHTTPリクエスト(URLとHTTPメソッド)に合致しているUsersコントローラーのindexアクションに割り振られる。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「Railsサーバーはリクエストをroutesに送り、」という表現は若干語弊があるかなと思いました。

まずリクエストを送るのはサーバではなくクライアントです。
また、リクエストを送る先はサーバ(Railsアプリケーションと言ってもいいかも)です。

で、Railsアプリの仕組み的にroutes.rbに定義されているルーティングをもとに利用されるコントローラ#アクションが決定されるという流れです。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POSTの方も同様。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙇‍♀️
確かに!言葉が大分曖昧になってました!

  • ご指摘箇所文章修正

WEBブラウザからリクエストを受け取ったサーバ(Railsアプリケーション)はroutes.rbに定義されているルーティングをもとに利用されるコントローラ#アクションが決定される。今回の場合だとUsersコントローラーのindexアクションに割り振られる。
(POSTも同じく修正します!)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK!!

Comment on lines 143 to 144
`form_with`は、HTML側に`method="post"`を自動で設定してくれる。
また`persisted?`メソッドでデータベースに値があるかを確認しfalseなら新規登録(create)、trueなら更新(update)といった判断ができるようになっているのでaction属性も自動的に判別し設定してくれる。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

end

```
フォームで入力されたパラメーター(値)は`form_with`によってcreateアクションへ渡された後、paramsメソッドを使用してデータベースに保存される。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

form_withによって」というのが語弊があるかもなと思いました。form_withはあくまでも<form>を生成するメソッドに過ぎません。なので厳密には<form>によってですね。また、formのactionってなにかわかりますか?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙇‍♀️
はい、formのaction属性は送信先のURLを指定する際に使用するものと一応認識しております。

  • ご指摘箇所文章修正

「パラメーター(値)はformによってcreateアクションへ渡された後、paramsメソッドを使用してデータベースに保存される。」

  • form_withについて

form_withformを生成するメソッドで、form_withでモデル、スコープ、URLを送信先として指定することにより、formaction属性に送信先のURLが自動的にセットされる。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paramsメソッドを使用してデータベースに保存される。

ここってどういうことでしょうか?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

大分定義が曖昧だったので改めて調べました!
確認お願いします🙇‍♀️

formから送られたパラメーターは、createアクションへ渡されるが、そのままの状態ではデータベースに保存することができないので、rails側でparamsメソッドを利用しハッシュ形式に変換してからデータベースへ保存される。

  • formでパラメーターを入力した後のparams[:task]の中身
[2] pry(#<TasksController>)> params[:task]
=> <ActionController::Parameters {"name"=>"a"} permitted: false>
  • データベース中身
sqlite> SELECT  "tasks".* FROM "tasks";
8|a|2021-04-13 15:50:13.841574|2021-04-13 15:50:13.841574|8

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そのままの状態ではデータベースに保存することができないので、

なぜ保存することができないんでしょうか??

別に

task = Taske.new
task.title = params[:task][:title]
task.body = params[:task][:body]
task.save

でも保存できるんですよね。

task = Task.new(task_params)

def task_params
  params.require(:task).permit(:title, :body)
end

が何をやっているのかを説明お願いします!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ほぼOKですね!

paramsにセットして定義する。

ここはちょっと違いますね。paramsはあくまでもparamsです。paramsに何かセットし直してるわけではないです。
デバッグしてparamsとparams.require(:task).permit(:title, :body)の返り値の違いを確認してみてください!

formのname=tasks[name]がrailsに送られたらハッシュ化されるっていう意味でそのままでは保存できないものなんだと解釈してました。

ここに関してもハッシュ化されること自体はまぁその通りなんですが、ハッシュ化される → 保存できないの論理が飛躍しすぎだと感じました。引数がハッシュでも別に保存はできるので。user = User.new({name: "dyson", age: 31}) のように。飛躍した論理で覚えちゃうと応用が効かなくなってしまうので注意しましょー。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paramsにセットして定義する。
paramsに何かセットし直してるわけではないです

ここ頭では理解はしてまして、ただ言葉が見つからなくて…セットって書いてしまいました!

[1] pry(#)> params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"juRR2sFlYE7wFLoeesabZWGj6FwfWPg//ySlXORI62WOq2zTvBUFpgsX0DrbrfQuQX2gqNxvKpmkQImCJ0A0Dg==", "task"=><ActionController::Parameters {“name"=>"b", "description"=>”b”} permitted: false>, "commit"=>"登録する", "controller"=>"tasks", "action"=>"create"} permitted: false>
[2] pry(#)> params.require(:task).permit(:name)
Unpermitted parameter: :description
=> <ActionController::Parameters {“name"=>”b”} permitted: true>
[3] pry(#)> params.require(:task).permit(:description)
Unpermitted parameter: :name
=> <ActionController::Parameters {"description"=>”b”} permitted: true>

中身同じですね!

そのままでは保存できないものなんだと解釈してました。

すいません、言い方が悪かったのですが一応だいそんさんの通りに理解をしていて、そのままを指しているのはハッシュではなくてformのname=tasks[name]を指してました。
pikawakaサイトでは噛み砕いて説明しているのだと、だいそんさんとラリーする中で理解しました!

飛躍した論理で覚えちゃうと応用が効かなくなってしまうので注意しましょー。

気をつけます!他のことでもその点気をつけて知識つけたいと思います!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formのname=tasks[name]

HTTPのform data

paramsに{ tasks: { name: "foobar" } }

ってのも認識してますかね??
参考
https://tech-essentials.work/courses/1/tasks/1/outputs/76

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

はい、上記の流れを今までの内容含めて簡単にまとめると

formのname=tasks[name]

上記データはPOSTでリクエストが送られる。

HTTPのform data

https://tech-essentials.work/courses/1/tasks/1/outputs/76
(抜粋)POSTメソッドの場合はHeadersのForm Dataという項目でリクエストした全てのFormの項目名と値を確認することが出来る。
POST

paramsに{ tasks: { name: "foobar" } }

サーバ(Railsアプリ)で受け取ったデータはハッシュ化され保存される。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ハッシュ化され保存される。

保存という言葉が気になりましたが、別にどこかに永続化されてるわけではないのでそこはお間違えのないよう!

@saeyama saeyama merged commit 3f940df into master Apr 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants