I've looked through every post I can imagine regarding this, but can't come across a solution. I have a Task with a nested resource of Task Products which grabs its ID's from another database. There can be multiple Task Products nested in a Task, and each one is dynamically created with some Javascript and an Application Helper (both of which are purely a copy/paste on my part).
I built up the code for these nested parameters with the help of Railscast 196/197 and this post. All the relevant code is below, and then onto the problem:
task.rb:
class Task < ApplicationRecord
has_many :task_products, :dependent => :destroy
accepts_nested_attributes_for :task_products, :reject_if => lambda { |p| p.values.all?(&:blank?) }, :allow_destroy => true
end
task_controller.rb:
class TasksController < ApplicationController
def new
@task = Task.new
@task.task_products.build
end
def task_params
params.require(:task).permit(:id, :task_name, . . ., :created_at, :updated_at,
:task_products_attributes => [:task_id, :product_id, :created_at, :updated_at])
end
application_helper.rb:
module ApplicationHelper
def new_child_fields_template(form_builder, association, options = {})
options[:object] ||= form_builder.object.class.reflect_on_association(association).klass.new
options[:partial] ||= association.to_s.singularize
options[:form_builder_local] ||= :f
content_tag(:div, :id => "#{association}_fields_template", :style => "display: none") do
form_builder.fields_for(association, options[:object], :child_index => "new_#{association}") do |f|
render(:partial => options[:partial], :locals => { options[:form_builder_local] => f })
end
end
end
application.js:
$(function() {
$('form a.add_child').click(function() {
var association = $(this).attr('data-association');
var template = $('#' + association + '_fields_template').html();
var regexp = new RegExp('new_' + association, 'g');
var new_id = new Date().getTime();
$(this).parent().before(template.replace(regexp, new_id));
return false;
});
});
_form.html.erb:
<%= form_for @task, url: tasks_path, method: :post, :html => {:multipart => true } do |f| %>
<%= f.fields_for :task_products, TaskProduct.new do |builder| %>
<%= render "task_product", :f => builder %>
<% end %>
<p><%= add_child_link "Add Product", :task_products %></p>
<%= new_child_fields_template f, :task_products %>
_task_product.html.erb:
<div class="fields">
<div class="form-group">
<%= f.label :product_id, "Product:", class: 'col-sm-3 control-label' %>
<%= f.collection_select(:product_id, @items, :id, :item_select, {:include_blank => 'Select Item...'}, {:class => 'form-control'}) %>
<%= remove_child_link "Remove Product", f %>
</div>
</div>
Code in console after submit along with the error it produced:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"KDQ...8bxur2A==",
"task"=>{"task_type"=>"Store Order",
"task_products_attributes"=>{
"0"=>{"product_id"=>"1", "_destroy"=>"false"},
"1484792726712"=>{"product_id"=>"2", "_destroy"=>"false"},
"new_task_products"=>{"product_id"=>"", "_destroy"=>"false"}},
"initiated_by"=>"1", "initiated_for"=>"5", "active"=>"true", "status"=>"Pending Acceptance"},
"commit"=>"Create Task"}
Unpermitted parameters: 0, 1484792726712, new_task_products
Generated HTML examples of error producing code of multiple generated selects:
<select class="form-control" name="task[task_products_attributes][0][product_id]" id="task_task_products_attributes_0_product_id">
<select class="form-control" name="task[task_products_attributes][1484794199756][product_id]" id="task_task_products_attributes_1484794199756_product_id">
and its template, which I thought should be throwing back ' "_destroy"=>true' in the console?:
<select class="form-control" name="task[task_products_attributes][new_task_products][product_id]" id="task_task_products_attributes_new_task_products_product_id">
The problem, as seen above, is that my generated Task Product form is adding an additional bracketed identifier(child index?) into my select box for each item, and I don't know how to dive into the Application Helper to remove it, or move it where it belongs. Or does it actually belong there and I'm doing something else wrong? I get the feeling that each individual Task Product should have it's own unique identifier, but Rails isn't having any of that and says its unpermitted.
The 'new_child_fields_template' in the Application Helper is a bit over my head, and while I understand how it's getting the unique identifier to inject into my Task Product form, I don't know how it's throwing it into the "name=" field of my select that is apparently screwing everything up. Anybody have some guidance on how I can overcome this problem? Thanks!
Aucun commentaire:
Enregistrer un commentaire