accepts_nested_attributes_for, validates_associated, and validates_presence_of within a has_many/belongs_to

In a popular Rails book:

it states that if want to make sure that the association is valid on a belongs_to, that is, make sure the parent is valid, then you use validates_associated in conjunction with validates_presence_of:

class Project < ActiveRecord::Base   has_many :tasks   accepts_nested_attributes_for :tasks end

class Task < ActiveRecord::Base   belongs_to :project

  validates_presence_of :project_id   validates_associated :project end

Unfortunately, this raises an issue because if the project validation fails, then it won't have an id, and then when Rails goes to validate the tasks, the task in turn will fail validation because they won't have a project_id. So why would the book suggest this? Or is it the accepts_nested_attributes_for that is causing the above behavior?

thanks for response

I need to rephrase this.

Here's the code:

class Project < ActiveRecord::Base   has_many :tasks   accepts_nested_attributes_for :tasks end

class Task < ActiveRecord::Base   belongs_to :project

  validates_presence_of :project_id   validates_associated :project end

Project.create!(   :name => 'Something',   :task_attributes => [ { :name => '123' }, { :name => '456' } ] )

The pattern of this is: * Validate Project * Validate Tasks * Save Project * Save Tasks

The book says: "if you want to make sure that the association is valid on a belongs_to, you have to use validates_associated in conjunction with validates_presence_of". And that is what the above code does.

But the problem with the above technique is that when we call create! on the project, it validates the project (and between :validate => true default on project an the validates_associated call on the belongs_to, these two calls prompt to check if the association are valid next), and since the project has not yet been saved, this will raise an error, because project_id does not exist yet, since the project has not been saved yet. So why does book say to use " validates_presence_of :project_id"?

Can you create the project first, saving it before you allow the user to even try to add tasks?

-Dave

But wouldn't your suggestion that defeat the purpose of using accepts_nested_attributes_for - where when someone submits a form with associations, it saves attributes on associated records through the parent by calling Parent.create, for example in the controller responding to the form request

It would defeat *a* purpose... not *the* purpose. They come in six-packs....

-Dave