#はじめに
Rails学習初期に、form_withの流れが理解できなかったのでまとめます。
Rails5.2.4です。
#先にまとめ
「早くまとめろよ!」という方もおられるかと思いますので、先に流れをまとめます。
#簡単に解説
UserモデルとPostモデルがある状況です。
①newアクションで、ビューページ(new.html.erb)を表示
newアクションを呼び出すリクエストが出されたら、まずはpostの新規投稿(new)ページが表示される
※イメージ
②newアクションで生成している@post
インスタンスをビューに渡す
class PostsController < ApplicationController
~~
def new
@post = Post.new #ここで生成されている@postが、new.html.erbに渡される
end
~~
④createアクションを呼び出す
上記の画像のように、投稿する
ボタン(form_withのsubmit)をクリックすると、form_withがcreateアクションを呼び出してくれます。
※form_withヘルパーメソッドは、渡されたインスタンス(この場合は
@post
)のプロパティを見て、createに飛ばすかupdateに飛ばすかを判断してくれる便利な子です。
- @post が空 → 初めて作るんだな!じゃあcreate!
- @post が空じゃない → 変更したいんだな!じゃあupdate!
⑤post_paramsメソッドを呼び出す
class PostsController < ApplicationController
~~
def create
#createアクションが呼び出され、Post.create(post_params)が実行される→ post_paramsが呼び出される
Post.create(post_params)
redirect_to root_path
end
private
def post_params
params.require(:post).permit(:title, :content).merge(user_id: current_user.id)
end
~~
⑥paramsで受け取った値のうち、permitで受け取る値を指定(許可)
[1] pry(#<PostsController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"oLGgLMTcqSPi7cbK9j1wFhH5rqiwXYO7GyRoZcZFZe6Y5VdbHrWCOyeo37kgW/bsl+eANQrz7p/lAzZMnAS8Gg==",
"post"=>{"title"=>"今日学んだこと", "content"=>"form_withは賢い子!"},
"commit"=>"投稿する", "exept"=>:index, "controller"=>"posts", "action"=>"create"} permitted: false>
見にくいので本来ない位置で改行していますが、通常は1行で返ってきます。
"post"=>{"title"=>"今日学んだこと", "content"=>"form_withは賢い子!"},
がpost_params
で扱う値です。
permit
で受け取る値を許可しておかないと、意図しない値がテーブルに保存される可能性があるので、指定がほぼ必須です。
⑦post_paramsの値でPostをcreateする(成功すればテーブルに保存される)
post_paramsメソッドで返された値で、Post.createすることになるので、
実質下記と同じ状態です。
def create
Post.create(title: "今日学んだこと", content: "form_withは賢い子!", user_id: 1)
redirect_to root_path
end
この流れを確認した上で、もう一度冒頭の画像を見ると理解が深まると思います!
#おわりに
form_tag、form_forとの違いはこちらの記事にまとめています。
[Rails]hamlでのform_with/form_for/form_tagの書き方
間違い等ありましたらご指摘いただけると幸いです。