railsのgemであるcocoonを用いて1対nのネストした投稿フォームを作る
railsのgemであるcocoonを用いて1対nのネストした投稿フォームを作る:
一つのフォームで親子関係のある複数モデルのレコード作成かつ子モデルのレコードを複数挿入したい場合にgemのcocoonを使うと簡単に実装できます。
今回はタイトルしか挿入しない投稿フォームに子モデルのタグを複数挿入する機能を実装します。
(タイトルカラムのあるPostモデルとタグカラムのあるTagモデルは1対Nの関連付けがあることが前提で進めます。)
scaffoldを使い、親モデルのレコードを作成できるようにします。
子モデルを作成します。
今回は子モデル名をTagにします。(カラムはタグを格納するためのnameカラムpost_idが必要)
PostモデルとTagモデルに関連付けを行います。
ネストしたフォームを作成するためにposts_controller.rbのnewアクションと_form.html.erbを編集します。
ここまでの記述でPostモデルとその子モデルのTagモデルのレコードの挿入を一つのフォームでできるはずです。
次に一つの親モデルに対し複数の子モデルのレコードを挿入できるように編集していきます。
タグのフォームを部分テンプレートにするためファイルを作成します
動的に要素を増やすためjsも変更します。
cocoonを使うと簡単にネストしたフォームを作成できます。
便利ですが正しい記述をしないと投稿や要素の追加や削除ができない場合があります。
要素(DOM)の操作はjqueryが便利です。
cocoonを使わずjqueryで実装するのも良いと思います。
はじめに
一つのフォームで親子関係のある複数モデルのレコード作成かつ子モデルのレコードを複数挿入したい場合にgemのcocoonを使うと簡単に実装できます。今回はタイトルしか挿入しない投稿フォームに子モデルのタグを複数挿入する機能を実装します。
(タイトルカラムのあるPostモデルとタグカラムのあるTagモデルは1対Nの関連付けがあることが前提で進めます。)
実装
シンプルな投稿フォームの作成
scaffoldを使い、親モデルのレコードを作成できるようにします。$ rails new cocoon_sample $ cd cocoon_sample
$ rails g scaffold Post title:string $ rails db:migrate
今回は子モデル名をTagにします。(カラムはタグを格納するためのnameカラムpost_idが必要)
$ rails g model Tag name:string post_id:integer $ rails db:migrate
post.rb
...(追加) has_many :tags, dependent: :destroy accepts_nested_attributes_for :tags, allow: true
tag.rb
belongs_to :post
posts_controller.rb
def new @post = Post.new @post.tags.build end ...(省略) def post_params params.require(:post).permit(:title, tags_attributes: [:id, :name, :_destroy]) end
_form.html.erb
...(省略) <%= form.fields_for :tags do |f| %> <%= f.label :name %> <%= f.text_field :name %> <% end %> <div class="actions"> <%= form.submit %> </div>
次に一つの親モデルに対し複数の子モデルのレコードを挿入できるように編集していきます。
_form.html.erb
<div class="tags"> <%= form.fields_for :tags do |f| %> <%= f.label "タグ" %> <%= render "tag_fields", f: f %> <% end %> <div class="links"> <%= link_to_add_association "タグを追加", form, :tags %> </div> </div>
views/posts/_tag_fields.html.erb
<div class="nested-fields"> <%= f.text_field :name %> <%= link_to_remove_association "remove task", f %> </div>
application.js
...(省略) //= require rails-ujs //= require activestorage //= require jquery ...(追加) //= require cocoon ...(追加) //= require turbolinks //= require_tree .
最後に
cocoonを使うと簡単にネストしたフォームを作成できます。便利ですが正しい記述をしないと投稿や要素の追加や削除ができない場合があります。
要素(DOM)の操作はjqueryが便利です。
cocoonを使わずjqueryで実装するのも良いと思います。
コメント
コメントを投稿