0

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.

NothingToSeeHere
  • 2,253
  • 5
  • 25
  • 57
  • When doing nested forms I usually also have to add ```_attributes``` to the ```attr_accessible``` list. So in your case, ```attr_accessible :participants_attributes```. Not sure if that's still the case in Rails 4. Also you should not need ```@participant = Participant.new``` in your ```create``` action. That's not doing anything. – Samo Mar 04 '15 at 17:20
  • Thank you, but attr_accessible is not longer needed... it's been replaced by strong params.....http://stackoverflow.com/questions/17371334/how-is-attr-accessible-used-in-rails-4 – NothingToSeeHere Mar 04 '15 at 17:22
  • Do your participant fields even show up on the form? – Samo Mar 04 '15 at 17:27

2 Answers2

1

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.

Samo
  • 8,202
  • 13
  • 58
  • 95
  • Thank you, I will have to try this later...as I am out. – NothingToSeeHere Mar 04 '15 at 17:29
  • The :participants fields WEREN'T showing up..you were right. I added @project.participants.build and they show up...but it doesn't create my parent and child, it calls the "else" redirect and redirects back to "new_project".... – NothingToSeeHere Mar 05 '15 at 15:35
  • 1
    If it's not saving, one of the objects must be invalid. Try to inspect the properties of ```@project``` and ```@project.participants.first``` before you save. See what's missing. Or use ```save!``` to throw an exception, which should tell you which validation failed. – Samo Mar 05 '15 at 18:04
  • Yup. I was missing a required field. Thank you! – NothingToSeeHere Mar 06 '15 at 13:58
0
  1. As you're using Rails 4 in your application, you don't need to call accepts_nested_attributes_for, because you are already calling params.requirein your Controller.
  2. After @participant = Participant.new you didn't call Participant.saveaction. You do call a @project.save inside your if condition and you should do that for your @participant too. You can call @project.save before redirecting to project_path. I'm not sure if that is a correct approach, but you can try if it works. :-)
ZuzannaSt
  • 375
  • 1
  • 13