Fields_for/pseudoattribute approach failing on create parent (b/c parent not saved?)

Hey All,

I’m trying to use the railscasts ep 75 approach to including multiple
models on a single form, by using fields_for to load up a
pseudoattribute. My ‘parent’ model is a Project, and the ‘child’ is a
ProjectPerson. It works fine when I’m editing an existing project, but
when I’m creating a new project, I get a validation error for each
ProjectPerson: “Project can’t be blank”. I’m guessing that means that
the project’s id is not getting copied over to the ProjectPerson’s
project_id, but I’m not sure how to make that happen. I expected it to
happen automatically (shouldn’t it?), but even if I try to do it myself
explicitly (see below) it doesn’t seem to work. I’m using rails v2.0.2.

Here is an example of the parameters that my projects/new form hands to
the projects/create action:

Parameters:
{“commit”=>“Create”
, “project”=>
{“name”=>“Roys Cool Project”
, “abbreviation”=>“RCP”
, “funding_mechanism”=>""
, “new_research_area_attributes”=>[{“research_area_id”=>""}]
, “grant_number”=>""
, “id”=>""
, “new_project_person_attributes”=>[{“role”=>“Programmer”,
“person_id”=>“9”}]
, “description”=>""
, “status_id”=>“2”
, “funder_id”=>""
, “start_date(1i)”=>""
, “start_date(2i)”=>""
, “start_date(3i)”=>""
, “end_date(1i)”=>""
, “end_date(2i)”=>""
, “end_date(3i)”=>""}
, “#ProjectPerson:0x4ad1494”=>{“role”=>“Programmer”}
, “authenticity_token”=>“08f382d5ec07eecec7cd229ce67664094516ed26”
, “action”=>“create”
, “#ProjectPerson:0x4ad6a70”=>{“role”=>“Programmer”}
, “controller”=>“projects”
, “name_search”=>“r”}

Projects/create is scaffold-written–it just does a

@project = Project.new(params[:project])
respond_to do |format|
if @project.save
flash[:notice] = ‘Project was successfully created.’
<<etc.>>

The relevant bits of the project model are:

class Project < ActiveRecord::Base
has_many :project_person, :dependent => :delete_all

after_update :save_personnell

def new_project_person_attributes=(personnell)
  personnell.each do |person|
    project_person.build(person)
  end
end

def save_personnell
  # raise("boobies!")
  project_person.each do |p|
    p.project_id = id  # <-- no effect!
    p.save(false)
  end
end

end # class Project

Can any of you kind folks advise on how I can fix (or further debug)
this problem?

Thanks!

-Roy

Roy P.
Research Analyst/Programmer
Group Health Center For Health Studies (Cancer Research Network)
(206) 287-2078
Google Talk: rpardee

Found my problem. I was being anal-retentive, and had put this in my
child model (ProjectPerson)

validates_presence_of :project_id, :person_id

If I comment that out, I can save the parent record no problem. So I
guess AR is calling .valid? on the child before trying to save it to the
db?

I guess I’ll have to ensure I don’t get nulls in those fields via db
constraints.

Frustrating to have lost so much time to that…

Cheers,

-Roy