Edited at

Rails フォーム(form_for,nested_form,fields_for) による複数同時投稿(親子、親子孫、他人)


index


1.親子同時投稿


2.他人同時投稿


3.親子孫同時投稿

railsの投稿において大事なことは2つで、どのようにしてパラメータを送るかと、それをどういうストロングパラメータによってコントローラーで受け取るかであると思う。そのためここではformの書き方、ストロングパラメータの書き方だけを紹介する。自分でjsを書くなどといったことは一切やらず、出来るだけシンプルにやっている。モデルや、コントローラーなどは単体で投稿する時とほとんど変わらない


1.親子同時投稿

ここではgem 'nested_form'を使う。cocoonでも同じことが出来る。

<%= nested_form_for @post do |f| %>

<%= f.label :title %>
<%= f.text_field :title %>

<%= f.fields_for :post_images do |t| %>
<%= t.label :image %>
<%= t.attachment_field :image %>
<%= t.link_to_remove 'delete' %>
<% end %>
<%= f.link_to_add 'add', :post_images %>
<%= f.submit %>
<% end %>

ストロングパラメータ

private

def post_params
params.require(:post).permit(:title,post_images_attributes: [:id, :image, :comment, :_destroy])
end


2.他人同時投稿

これはpostが送られなさそうだが、パラメータをみて見るとちゃんと送られている。

<%= form_for(@book) do |f| %>

<div>book_title</div>
<div><%= f.text_field :title %></div>
<div>book_body</div>
<div><%= f.text_field :body %></div>

<%= fields_for(@post) do |t| %>
<div>post_title</div>
<%= t.text_field :title %>
<% end %>
<%= f.submit "toukou" %>
<% end %>

 Parameters: {"utf8"=>"✓", "authenticity_token"=>"#####", "book"=>{"title"=>"ddd", "body"=>"dd"}, "post"=>{"title"=>"ddd"}, "commit"=>"toukou"}

ストロングパラメータは二つのモデルに対して、別々に書けばいいだけ。


3.親子孫同時投稿

これがもっとも難しかった。1.と同じくnested_formというgemを使って作る。group

が親、memberが子、petが孫である。

new.html.erb、_member_fields.html.erb、_pet_fields.html.erbという3つのviewページが必要である。


new.html.erb

<%= nested_form_for(@group) do |f| %>

<%= f.label :group_name %>
<div class="group_name"><%= f.text_field :group_name, class: "field" %></div>
<div class="members_field">
<div class="member_name"><%= f.fields_for :members %></div>
<div class="member_name"><%= f.link_to_add 'member_add', :members %></div>
</div>
<%= f.submit %>
<% end %>


_member_fields.html.erb

<div class=""><%= f.label :member_name %></div>

<div class=""><%= f.text_field :member_name,class: "field" %></div>
<div class="pet_name"><%= f.fields_for :pets %></div>
<div class="pet_name"><%= f.link_to_add 'pet_add', :pets %></div>


_pet_fields.html.erb

<div class=""><%= f.label :pet_name %></div>

<div class=""><%= f.text_field :pet_name, class: "field" %></div>

こういう感じのネストされたパラメータが送られる

Parameters: {"utf8"=>"✓", "authenticity_token"=>"###", "group"=>{"group_name"=>"gropu1", "members_attributes"=>{"0"=>{"member_name"=>"member1", "pets_attributes"=>{"0"=>{"pet_name"=>"pet1-1"},

"1538144621725"=>{"pet_name"=>"pet1-2"}, "1538144623037"=>{"pet_name"=>"pet1-3"}}}, "1538144619585"=>{"member_name"=>"member2", "pets_attributes"=>{"1538144620711"=>{"pet_name"=>"pet2-1"}, "1538144624584"=>{"pet_name"=>"pet2-2"}}}}}, "commit"=>"Create Group"}

ストロングパラメータはこんな感じ

params.require(:group).permit(:group_name,:members_attributes => [:id, :member_name, :_destroy, :pets_attributes => [:id, :pet_name, :_destroy]])

以上で終わりです。まだいい方法がありそうなので、あったら教えてください。