Railsアプリで1対多のモデルを、動的なフォームで複数登録・更新したい
前提条件と実現したいこと
Taskモデル(親)とTaskBranchモデル(子)を作成し、
フォームからのタスク登録時に複数のタスクブランチを登録したいです。
TaskBranchの数は任意の数を選択できるように動的なフォームにしてあります。
cocoon gem などは使用せずに実装できないかとトライしています。
model
1class Task < ApplicationRecord 2 has_many :task_branches, inverse_of: :task 3 accepts_nested_attributes_for :task_branches, allow_destroy: true 4 5class TaskBranch < ApplicationRecord 6 belongs_to :task, inverse_of: :task_branches 7 validates_presence_of :task
form
1<%= form_for(@task, html:{class:"form-signin border border-white"}) do |f| %> 2<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 3<script type="text/javascript"> 4$(document).on("click", ".add", function() { 5 $(this).parent().clone(true).insertAfter($(this).parent()); 6}); 7$(document).on("click", ".del", function() { 8 var target = $(this).parent(); 9 if (target.parent().children().length > 1) { 10 target.remove(); 11 } 12}); 13</script> 14 15 <div class="form-row"> 16 <div class="input-group-prepend col-lg-4 mb-3"> 17 <%= f.label :title, class: "input-group-text"%> 18 <%= f.text_field :name, class:"form_control" %> 19 </div> 20 </div> 21. 22. 23. 24 <%= f.fields_for :task_branches do |branch_f| %> 25 <div class="form-row"> 26 <div class="input-group-prepend col-lg-4 mb-3"> 27 <%= branch_f.label :項目, class: 'input-group-text' %> 28 <%= branch_f.text_field :name, class:'form_control md-4',:placeholder => "項目" %> 29 <input type="button" value="+" class="add"> 30 <input type="button" value="-" class="del"> 31 </div> 32 </div> 33 <% end %> 34 35 <%= f.submit "タスクを追加する", class: "btn btn-primary btn-block my-2" %> 36<% end %>
困っていること
動的に追加した子モデル(TaskBranch)要素が親モデル(Task)に対して
一つしか登録できずに困っています。
tasks.controllerにて
def show @task = Task.find(params[:id]) @task_branch = @task.task_branches end
のようにインスタンス変数を定義し、@taskに紐づくtask_branchesを取り出すことが目標です。
試したこと
・formにてfields_forを使用し、1対多のリレーションを元に送信し、
親のTasksControllerでは
task_branches_attributes:
とし子モデルの情報をStrongParameterで送信しています。
taskcontroller
1class TasksController < ApplicationController 2 before_action :set_task, only: [:show, :edit, :update, :destroy] 3 4 def new 5 @task = Task.new 6 @task.task_branches.build 7 end 8 9 def create 10 @task = Task.create(task_params) 11 if @task.save 12 redirect_to @task 13 else 14 render :new 15 end 16 end 17 18 def show 19 @task = Task.find(params[:id]) 20 @task_branch = @task.task_branches 21 end 22 23 private 24 25 def set_task 26 @task = Task.find(params[:id]) 27 end 28 29 def task_params 30 params.require(:task).permit(:name, :category, :description, task_branches_attributes: [:name,:check, :_destroy]) 31 end 32end
_form.html.erb内で
f.fields_forの内容を複製している箇所にて
子モデルの任意で追加する項目が全て同じ内容なことが
原因となっているのではと考えているのですが、うまくいきません。
1対多のリレーションのモデルかつ
動的なフォームにより作成するアドバイスを頂けると幸いです。
補足情報(FW/ツールのバージョンなど)
モデルのカラムは以下のように設定
create_table "task_branches", force: :cascade do |t| t.string "name" t.boolean "check" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.integer "task_id", null: false t.index ["task_id"], name: "index_task_branches_on_task_id" end create_table "tasks", force: :cascade do |t| t.string "name" t.string "category" t.string "description" t.integer "branch_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end
Rails 6.0.3 /ruby 2.6.3です
あなたの回答
tips
プレビュー