formで2つのモデルを送信する方法について書く。
これは自分用のメモである。
結論から言うと、form_forにネストして、fields_forを使う。
1.view
new.html.erb
<%= form_for(@post) do |f| %>
<%= f.label:title %>
<%= f.text_field:title %>
<%= f.label:content %>
<%= f.text_field:content,size:50 %>
<%= fields_for :category ,(@categroy) do |category| %>
<%= category.label:category %>
<%= category.text_field:category %>
<% end %>
<%= f.submit "提出する" %>
<% end %>
上記のように、field_forを書けば、
Parameters: {"utf8"=>"✓", "authenticity_token"=>"JxEgfX0JBqa9LyqTMtGPN/L20XcLJTL0AznQgIdpaWK8GHbcS/lIuKHZnBO7d4aHlClQM2SDp1s04iT4zyfeji==", "post"=>{"title"=>"もしやこれは...", "content"=>"gegt"}, "category"=>{"category"=>"プログラミング"}, "commit"=>"提出する"
上記のように、送信される。なおわかりにくいが、categoryモデルにはcategoryと言うカラムがある。
注意点として、field_forを書く時は、:categoryと言う引数が必要になる。これは、views/posts/new.html.erbのため、postリソースの文脈にあるからだ。categoryをformで送る際は、入れる箱を明示しないといけない。なぜなら、文脈外の行動だからである。
このようにして、2つのモデルを扱ってformの送信ができた!
2.controller
PostsController.rb
class PostsController < ApplicationController
def show
@post=Post.find(params[:id])
end
def new
@post=Post.new
@category=Category.new
end
def create
category=Category.find_by(category_params)
@post=category.posts.build(post_params)
if @post.save
render 'normal/home'
else
redirect_to root_url
end
end
private
def category_params
params.require(:category).permit(:category)
end
def post_params
params.require(:post).permit(:title,:content)
end
end
上記には2つ注意点があり。
1.newメソッドでは2つのインスタンス変数を作ること。
2.ストロングパラメーターも2つ作る。
なお、ストロングパラメーターは、
"post"=>{"title"=>"もしやこれは...", "content"=>"gegt"},
"category"=>{"category"=>"プログラミング"}
のように、ハッシュで渡されるので注意が必要。値だけが渡されるものではない。
以上です。