リクエストからレスポンスまでの流れについて(GET編)
とあるSNSアプリがあります。ユーザーの一覧ページがブラウザに表示されるまで
- ユーザーがWebブラウザにて、一覧表示に遷移するため/userのURLが設定されているリンクを押す
↓ - /userに対してGETメソッドでリクエストがサーバに送信される
↓ - Webサーバーがリクエストを受け取り、routes.rbにてルーティング機能がそのリクエストの処理をすべきコントローラー(クラス)とアクション(メソッド)を特定し、アクションを実行します。
↓ - コントローラーのアクションにてUser.allを呼び出し、Userモデルを通してusersデータベースからコレクション(ドキュメントの集合体)を読み込む。
↓ - インスタンス変数@usersにコレクションが代入される
↓ - @usersがビューで展開され、クライアントにレンダリングされます
リクエストからレスポンスまでの流れについて(POST編)
とあるタスク管理アプリがあり,
タスクを新規作成するときの流れにそって解説
新規作成ページを表示する
- まず初めに以下のような画面の新規登録画面ボタン(/tasks/newのリンク)をクリックします。
- /tasks/newに対してGETリクエストが送られる
- Webサーバーがリクエストを受け取り、routes.rbにてルーティング機能がそのリクエストの処理をすべきコントローラー(クラス)とアクション(メソッド)を特定し、アクションを実行します。
『newアクションでTask.newで空のインスタンスを作り、@taskに代入。』
#tasks_controller.rb
def new
@task = Task.new
end
- 新規登録ページ(new.html.slim)がクライアントにレンダリングされる
/new.html.slim
= form_with model: task, local: true do |f|
.form-group
= f.label :name
= f.text_field :name, class: 'form-control', id: 'task_name'
.form-group
= f.label :description
= f.text_field :description, row: 5, class: 'form-control', id: 'task_description'
=f.submit nil, class: 'btn btn-primary'
タスク名(name)を入力する
- 名称 のフォーム内にタスク名を入力する『ビールの発注をする』
※今回、詳しい説明 と書いてあるフォームの説明は省略する
表示されているフォームの部分は、form_with
というヘルパーメソッドを使っており、以下のような使い方をします。
⬇️
①
データベースに保存しない場合のform_withの書き方
<%= form_with url: "パス" do |form| %>
フォーム内容
<% end %>
②
データベースに保存する場合のform_withの書き方
<%= form_with model: モデルクラスのインスタンス do |form| %>
フォーム内容
<% end %>
今回は②を使い
/new.html.slim
= form_with model: task, local: true do |f|
.form-group
= f.label :name
= f.text_field :name, class: 'form-control', id: 'task_name'
.form-group
= f.label :description
= f.text_field :description, row: 5, class: 'form-control', id: 'task_description'
=f.submit nil, class: 'btn btn-primary'
となっています。そして、上記のビューファイルは以下のようなHTMLファイルを生成します。
いくつか説明します。
-
action
は送信先のURLを指定します。"/tasks"ということはcreateアクションのURLが指定されているということです。 -
method
はPOSTのHTTPリクエストを指定しています。 -
name=tasks[name]
は、params = { task: { name: "タスク名"}}のように、フォームデータが2重のハッシュ構造を持たせられる
作成ボタンを押す
-
ルーティングで
tasks#create
のコントローラーとアクションが実行されます。
tasksコントローラのcreateアクション
def create
@task = Task.new(task_params)
end
ストロングパラメータであるtasks_paramsで受け取った値をnewメソッドの引数として、Taskモデルのインスタンスを生成します。
@task
に代入します。
タスクの詳細画面に遷移する
- if文を用いてデータベースへの保存が成功した際に詳細ページに遷移するよう分岐します。保存に失敗した際は新規登録ページに
tasksコントローラのcreateアクション
def create
@task = Task.new(task_params)
if @task.save
redirect_to @task, notice: "タスク「#{@task.name}」を登録しました"
else
render :new
end
end
-
詳細ページに遷移する際には
redirect_to @task
によりtasksコントローラのshowアクションが呼び出され、クライアントからGETリクエストが発生する。
↓ -
ルーティングで対応する
tasks#show
が実行される
↓ -
showアクションが起動され、データベースから取得したデータが@taskに代入される
def show
@task = Task.find(params[:id]) #パラメーター経由で対象タスクのIDを受け取り、タスクオブジェクトをデータベースから取得
end
-対応するビューファイルであるshow.html.slim
がクライアントにレンダリングされる。
h1 タスクの詳細
nav.jusfity-content-end
= link_to "一覧", tasks_path, class: "nav-link"
table.table.table-hover
tbody
tr
th= Task.human_attribute_name(:id)
td= @task.id
tr
th= Task.human_attribute_name(:name)
td= @task.name
tr
th= Task.human_attribute_name(:description)
td= simple_format(h(@task.description), {}, sanitize: false, wrapper_tag: "div")
tr
th= Task.human_attribute_name(:created_at)
td= @task.created_at
tr
th= Task.human_attribute_name(:updated_at)
td= @task.updated_at
= link_to "編集", edit_task_path, class: "btn btn-primary mr-3"
= link_to "削除", @task, method: :delete, data: { confirm: "タスク『#{@task.name}』を削除します。よろしいですか?" }, class: "btn btn-danger"