Hinzufügen mehrerer verschachtelter Attribute über Kontrollkästchen Rails 4 (möglicherweise mit mehreren Formularen)
3/13 UPDATE:
Ich habe ein kleines Beispielprojekt mit meinen Modellen, der Steuerungslogik und verschiedenen Formularversionen erstellt.
Ich erstelle ein Formular, in dem ein Benutzer "Aufgaben" und "Meilensteine" zusammenfügen kann. (dh Aufgabe = 'Vakuum' befindet sich innerhalb von Milestone = 'Clean House'). Grundsätzlich handelt es sich um ein Modell vom Typ Task / Subtask, bei dem das übergeordnete Element 'Milestone' und das untergeordnete Element 'Task' ist.
Beide Aufgaben und Meilensteine gehören zu "Projekt". Ich versuche daher, die Aufgaben und Meilensteine über ein verschachteltes Formular mit einer Aktualisierungsaktion hinzuzufügen. Ich denke, der Weg ist, ein Formular für jede Instanz von @task_template zu erstellen und mehrere Formulare gleichzeitig zu aktualisieren.
Mein Problem ist, dass ich auch versuche, "Starter-Meilensteine / Aufgaben" über Tabellen mit den Namen "MilestoneTemplates" und "TaskTemplates" dynamisch festzulegen ....
Der Benutzer ruft die Seite "Meilensteine / Aufgaben hinzufügen" auf und sieht je nach Projekttyp neben den Kontrollkästchen eine Reihe vorgefertigter Aufgaben (@task_templates) und Meilensteine (@milestone_templates). Der Benutzer KONTROLLIERT dann das Kontrollkästchen neben der Aufgabe oder dem Meilenstein, die bzw. den er hinzufügen möchte. Dies sollte eine spezifische Aufgabe für den Benutzer mit einer vorgefertigten @ task_template.name, @ task_template.description ... etc @ erstelle
Ich kann nicht einmal 1 erstellen. Ich verwende Rails 4 und glaube, ich habe meine strong_params richtig eingestellt. Hier bin ich:
Models:
class Task < ActiveRecord::Base
belongs_to :user
belongs_to :project
belongs_to :milestone
class Milestone < ActiveRecord::Base
belongs_to :project
belongs_to :user
has_many :tasks, dependent: :destroy, inverse_of: :milestone
accepts_nested_attributes_for :tasks, allow_destroy: true
class Project < ActiveRecord::Base
has_many :milestones, dependent: :destroy
has_many :tasks, dependent: :destroy
accepts_nested_attributes_for :tasks, allow_destroy: true
accepts_nested_attributes_for :milestones, allow_destroy: true
#the "Starter Milestones & Tasks"
class MilestoneTemplate < ActiveRecord::Base
has_many :task_templates, dependent: :destroy, inverse_of: :milestone_template
class TaskTemplate < ActiveRecord::Base
belongs_to :milestone_template, inverse_of: :task_templates
Regler
class ProjectsController < ApplicationController
def new_milestones
@project = Project.find(params[:p])
@project.milestones.build
@project.tasks.build
@milestones_templates = MilestoneTemplate.where(template_id: @project.template_id)
end
def create_milestones
@project.milestone_ids = params[:project][:milestones]
@project.task_ids = params[:project][:tasks]
@milestone = Milestone.new
@task = Task.new
@template = Template.find( @project.template_id)
if @project.update_attributes(project_params)
redirect_to view_milestones_path(p: @project.id)
flash[:notice] = "Successfully Added Tasks & Milestones"
else
redirect_to new_milestones_path(p: @project.id )
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
def project_params
params.require(:project).permit( :id, :name,
milestones_attributes: [:id, {:milestone_ids => []}, {:ids => []}, {:names => []}, :project_id, :user_id,
:name, :description, :due_date, :rank, :completed, :_destroy,
tasks_attributes: [:id, {:task_ids => []}, {:names => []}, {:ids => []}, :milestone_id, :project_id,
:user_id, :name, :description, :due_date, :rank, :completed, :_destroy]] )
end
end
Form Test 1:
<%= form_for @project, url: create_milestones_path(p: @project.id) do |f| %>
<label>Milestones</label><br>
<div class="row">
<%= hidden_field_tag "project[names][]", nil %>
<% @milestones_templates.each do |m| %>
<%= check_box_tag "project[names][]", m.name, @milestones_templates.include?(m), id: dom_id(m)%>
<%= label_tag dom_id(m), m.name %>
<%= hidden_field_tag "project[milestone][names][]", nil %>
<% m.task_templates.each do |t| %>
<%= check_box_tag "project[milestone][names][]", t.name, m.task_templates.include?(t), id: dom_id(t) %>
<%= label_tag dom_id(t), t.name %>
<% end %>
<% end %>
</div>
<%= f.submit %>
Form Test 2 (versucht ein Array von Formularen zu senden):
<label>Milestones</label><br>
<%= hidden_field_tag "project[milestone_ids][]", nil %>
<% @milestones_templates.each do |m| %>
<div>
<%= f.fields_for :milestones do |fm|%>
<%= check_box_tag "project[milestone_ids][]", @milestones_templates.include?(m), id: dom_id(m) %>
<%= label_tag dom_id(m), m.name %></div>
<%= hidden_field_tag :name, m.name %>
<%= hidden_field_tag "project[milestone][task_ids][]", nil %>
<% m.task_templates.each do |t| %>
<%= fm.fields_for :tasks do |ft| %>
<%= check_box_tag "project[milestone][task_ids][]", t.name, m.task_templates.include?(t), id: dom_id(t)%>
<%= label_tag dom_id(t), t.name %>
<% end %>
<% end %>
<% end %>
<% end %>
</div>
as per xcskier56 Anfrage in den Kommentaren habe ich meinen POST-Code aus Chrome Inspector hinzugefügt. Wie Sie sehen, werden im Formular nicht einmal die Aufgaben aufgerufen, sondern nur die übergeordneten Meilensteine. Die Meilensteine werden im Formular angezeigt, die Aufgaben jedoch nicht.
project[formprogress]:2
project[milestone_ids][]:
project[milestone][names]:true
name:Milestone 1
project[milestone][task_ids][]:
project[milestone][names]:true
name:Milestone 2
project[milestone][task_ids][]:
project[milestone][names]:true
name:Milestone 3
project[milestone][task_ids][]:
project[milestone][names]:true
name:Milestone 4
project[milestone][task_ids][]: