Accepts_nested_attributes_for, validates_associated, and validates_presence_of within a has_many/bel

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"?

On Wed, Aug 1, 2012 at 12:09 AM, John M. [email protected] wrote:

this will
raise an error, because project_id does not exist yet, since the
project has not been saved yet.

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

-Dave


Dave A., Cleared/Remote Ruby on Rails Freelancer
(NoVa/DC/Remote); see www.DaveAronson.com, and blogs at
www.Codosaur.us, www.Dare2XL.com, www.RecruitingRants.com

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

On Aug 1, 10:41am, Dave A. [email protected]

On Wed, Aug 1, 2012 at 8:38 PM, John M. [email protected] wrote:

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


Dave A., Cleared/Remote Ruby on Rails Freelancer
(NoVa/DC/Remote); see www.DaveAronson.com, and blogs at
www.Codosaur.us, www.Dare2XL.com, www.RecruitingRants.com