経緯
新人研修でRuby on Railsを用いて簡単なタスク管理アプリを作成しています。新規登録時のデータの流れをチューターに説明する機会があったので、それに向けてアウトプットしつつ考えを整理したいと思って記事を書くことにしました。
元のコード(一部抜粋)
Rails.application.routes.draw do
root 'tasks#index'
resources :tasks
end
<% provide(:title, '新しいタスク') %>
<h1>新しいタスク</h1>
<%= form_with(model: @task, local: true) do |form| %>
<div class="field">
<%= form.label :title %>
<%= form.text_field :title, maxlength: 50 %>
<%= render 'shared/field_error', object: form.object, field: :title %>
</div>
<div class="field">
<%= form.label :description %>
<%= form.text_area :description, maxlength: 255 %>
<%= render 'shared/field_error', object: form.object, field: :description %>
</div>
<div class="actions">
<%= form.submit '登録', class: "button" %>
</div>
<% end %>
<%= link_to 'タスク一覧へ', tasks_path, class: 'button' %>
class TasksController < ApplicationController
~~~~~~~~~~~~~~~~
def create
@task = Task.new(task_params)
if @task.save
redirect_to tasks_path, notice: t('message.success.create', model: Task.model_name.human)
else
flash.now[:alert] = t('message.danger.create', model: Task.model_name.human)
render :new
end
end
private
def task_params
params.require(:task).permit(:title, :description)
end
def set_task
@task = Task.find(params[:id])
end
end
①フォームに入力された内容からPOSTリクエストを送る
見た目は全く整えていないです。。
この状態で登録ボタンを押すことで新しいタスクを登録できます。中で何が起こっているのか。
まず、復習なのですが
html の formを submit するとPOSTリクエスト を送ることができます
なので登録ボタンの
<%= form.submit '登録', class: "button" %>
この部分を押すとPOSTリクエストを送ることができます。
そしてこのPOSTリクエストには、リクエストパラメータというデータが添付されています。
送ったPOSTリクエストを検証で確認してみると、
ありました!
この今にもこのままDBに格納したくなるようなデータがリクエストパラメータというものらしいです。
コードのどの部分でこの形式を指定しているのか調べてみたら、
ハッシュのキーっぽい部分task[title]のtaskの部分は
<%= form_with(model: @task, local: true) do |form| %>
どうやらこの部分ですでに準備できているみたいです。
model:の部分でフォームのフィールドは、このモデルオブジェクトのtaskの属性(テーブルのカラム)に基づいて自動的に設定されるらしい。Railsすごい。
その属性(カラム)の部分は
<%= form.text_field :title, maxlength: 50 %>
ここのtitleの部分で定められているっぽいです。
なのでこの入力フォームに入力して登録ボタン(submit)を押すと、先ほどの画像のように、
task[title]:新しく登録
というリクエストパラメータを添付できるということでした。
そしてこのリクエストパラメータを持ったPOSTリクエストがルーティングされます。
②routes.rbに到着
Rails.application.routes.draw do
root 'tasks#index'
resources :tasks
end
送られてきたリクエストはroutes.rb記載通りにルーティングされます。
resourcesによって、RESTfulなルーティングが自動で設定されています。(ここではresourcesの説明については割愛)
ということで、tasks_controllerのcreateアクションに向かうことになりました。
③tasks_controllerに到着
class TasksController < ApplicationController
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def create
@task = Task.new(task_params)
if @task.save
redirect_to tasks_path, notice: t('message.success.create', model: Task.model_name.human)
else
flash.now[:alert] = t('message.danger.create', model: Task.model_name.human)
render :new
end
end
private
def task_params
params.require(:task).permit(:title, :description)
end
def set_task
@task = Task.find(params[:id])
end
end
ルーティングによってcreateアクションを実行します。
@ taskというインスタンス変数を作成しようと(task_params)を引数にTask.newを実行しようとしています
task_paramsってなんだと思ったら、下のprivateの部分に記載がありました。
params.require(:task).permit(:title, :description)
paramsというのは、HTTPリクエストのデータをRailsで使うために格納するハッシュのような、箱のようなオブジェクトです。(私のイメージ)
私はここを勘違いしていたのですが、
初期の状態ではparamsは、URLやフォームから送信されたすべてのパラメータが含まれているみたいです。
params.require(:task) によって初めて、全部が含まれたparamsという箱から :task キーに関連するデータを取り出すことを要求しています。(ハッシュのような形状なのでキーを指定して取り出せる)
permit(:title, :description) についてはストロングパラメータで悪意のある攻撃者からもろに攻撃を受けないように、受け取る属性(カラム)を制限しています。(本旨と関係が薄いので割愛)
以上の流れで
task[title]: 新しく登録
のようなデータを(task_params)に紐付けできたので、
@task = Task.new(task_params)
if @task.save
redirect_to tasks_path, notice: t('message.success.create', model: Task.model_name.human)
が実行されます。
ApplicationRecordを継承したTaskモデルによって、newメソッドやsaveメソッドが実行されて、さきほどのデータがDBに新規登録されました!
まとめ
自分なりに細かくまとめようと思いましたが、まだまだ深掘りできそうだなと思いました。Rails怖い。
検証しながら、調べながらの記事なので間違っている部分もあると思いますので、その際は教えていただけると助かります。。。