I am trying to automatically create a child record (Participant) when I create a parent (Project) record. I can create the parent (Project) fine and, on other forms, I can create the child (Participant). I cannot seem to create the child (Participant) at the same time as the parent.
I am on Rails 4, and so I've set my strong params carefully. I just don't understand what I'm doing wrong.
Parent Controller:
class ProjectsController < ApplicationController
def new_project
@title = params[:ti]
@project = Project.new
@project.participants.build
end
def create_project
@project = Project.new(project_params)
@template = Template.find(params[:t])
@project.participants.build
@title = params[:ti]
respond_to do |format|
if @project.save
@project.participants.save
format.html { redirect_to new_milestones_path(:p => @project.id), notice: 'Great! We saved your project details.' }
else
format.html { redirect_to new_project_path(t: @template.id, ti: @title)
}
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
def project_params
params.require(:project).permit( :id, :title, :starts, participants_attributes: [:id, :email, :title, :status, :project_id])
end
end
Models:
class Participant < ActiveRecord::Base
belongs_to :project, inverse_of: :participants
........
end
class Project < ActiveRecord::Base
has_many :participants, dependent: :destroy, inverse_of: :project
accepts_nested_attributes_for :participants, allow_destroy: true, reject_if: proc { |a| a["email"].blank? }
.........
end
Form:
<%= form_for @project, url: create_project_path(ti: @title), html: { :multipart => true, :class=> "form-horizontal", id: "basicForm" }do |f| %>
<%= f.fields_for :participants do |ff|%>
<%= ff.hidden_field :email, :value => current_user.email %>
<%= ff.hidden_field :title, :value => 'Organizer' %>
<%= ff.hidden_field :status, :value => 'accepted' %>
<% end %>
<%= f.text_field :title, :placeholder => 'Your Project Title'%>
<%= f.text_field :starts, :placeholder => 'mm/dd/yyyy'%>
<%= f.submit ' SAVE PROJECT' %>
<% end %>
UPDATE: I added @project.participants.build as Samo suggested (and I've updated my code above), which makes the fields_for visible...but my project doesn't save...it redirects back to new_project_path.
I believe I see the issue. In your new_project
action, try this:
def new_project
@title = params[:ti]
@project = Project.new
@project.participants.build
end
To elaborate: fields_for
is not going to render anything if the association is blank/empty. You need to have at least one participant
returned by @project.participants
in order to see its fields. @project.participants.build
will simply insert a new instance of the Participant
class into the association.