Rails 3 How to assign the value to nested attributes before calling save in update action

I am using Rails 3.0.9 and Ruby 1.9.2

Models associations are

document.rb

has_many :sections

accepts_nested_attributes_for :sections, :allow_destroy => :true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }

section.rb

belongs_to :document

has_many :paragraphs, :dependent => :destroy

has_many :contents :through => :paragraphs

validates :user_id, :presence => { :message => “Must be filled” }

paragraph.rb

attr_accessible :user_id, :section_id, :content_id

belongs_to :section

belongs_to :content

validates :user_id, :section, :content, :presence => { :message => “Must be filled” }

paragraphs table just like a intermediate table for sections and contents and I want to save records in documents, sections and paragraphs table using single form submission.

_form.html.erb

<%= form_for @document, :validate => true do |f| %>

<%= f.error_messages %>

<div><%= f.text_field :name %></div>

<% f.fields_for :sections do |builder| %>

	<div><%= builder.text_field :name %></div>

	<div><%= builder.select :content_ids, Content.all.collect {|p| [ p.name, p.id ] },{:prompt => "Please Select"}, {:class => "nhs_select", :multiple => true}  %></div>

<% end %>

<%= f.submit :submit%>

<% end %>

Example parameters when submiting the form

{“document”=>{“name”=>“sdf”, “sections_attributes”=>{“0”=>{“name”=>“sdf”, “description”=>“sdf”, “_destroy”=>“0”, “content_ids” => [“1”, “2”]}}, “commit”=>“Create Document”}

In additionally, I should need to update current_user’s id to user_id column of paragraphs table.

def create

@document = Document.new

@document.attributes = params[:document]

@document.sections.each {|section|

section.user_id = current_user.id

section.paragraphs.each {|paragraph| paragraph.user_id = current_user.id}

}

if @document.save!

success

else

render :action => ‘new’

end

end

Problem 1:

At first, I submit the form, rails render new form without error message even I have implemented code to display error messages.

then again clicked submit button, action goes to update method. But it should go to new action.

I inspected in console, the inserted records were rollbacked but still the ID is retain in object.

Example:

Problem 2:

Documentation said that the changes are not saved to the database when assigning the attributes as like user.attributes = {:name => “Rob”}.

but my case validation is triggered when assigning the attributes so I can’t assign the value to user_id column in paragraph object before calling save method

@document.attributes = {“sections_attributes”=>{“0”=>{“name”=>“sdf”, “content_ids” => [“1”, “2”]}}

or

section = Section.first

section.attributes = {“content_ids” => [“1”, “2”]}

How to assign the value to user_id in paragraph object before calling save method

Console Output

Started POST “/documents” for 127.0.0.1 at 2013-03-15 19:17:12 +0530

Processing by DocumentsController#create as HTML

Parameters: {“utf8”=>“✓”, “authenticity_token”=>“fvjouziWyDPCsTIJQvguXG1vvAIGy8ej5hR+69TTeIQ=”, “document”=>{“name”=>“sample”, “sections_attributes”=>{“0”=>{“name”=>“one”, “content_ids”=>[“1”, “2”]}}}, “commit”=>“submit”}

Content Load (0.0ms) SELECT contents.* FROM contents WHERE contents.id IN (1, 2)

SQL (0.1ms) BEGIN

SQL (0.0ms) COMMIT

SQL (0.0ms) BEGIN

SQL (0.3ms) describe documents

AREL (0.1ms) INSERT INTO documents (name, created_at, updated_at) VALUES (‘sample’, ‘2013-03-15 13:47:12’, ‘2013-03-15 13:47:12’)

SQL (0.3ms) describe sections

AREL (0.1ms) INSERT INTO sections (name, document_id, created_at, updated_at) VALUES (‘one’, 2, ‘2013-03-15 13:47:12’, ‘2013-03-15 13:47:12’)

Section Load (0.3ms) SELECT sections.* FROM sections WHERE sections.id = 3 LIMIT 1

Content Load (0.1ms) SELECT contents.* FROM contents WHERE contents.id = 1 LIMIT 1

SQL (72.5ms) ROLLBACK

Content Load (0.1ms) SELECT contents.* FROM contents

Rendered documents/_form.html.erb (4.8ms)

Rendered documents/new.html.erb within layouts/application (8.7ms)

Started POST “/documents/2” for 127.0.0.1 at 2013-03-15 19:17:48 +0530

Processing by DocumentsController#update as HTML

Parameters: {“utf8”=>“✓”, “authenticity_token”=>“fvjouziWyDPCsTIJQvguXG1vvAIGy8ej5hR+69TTeIQ=”, “document”=>{“name”=>“sample”, “sections_attributes”=>{“0”=>{“name”=>“one”, “content_ids”=>[“1”, “2”]}}}, “commit”=>“submit”, “id”=>“2”}

Document Load (0.2ms) SELECT documents.* FROM documents WHERE documents.id = 2 LIMIT 1

Completed 404 Not Found in 10ms

ActiveRecord::RecordNotFound (Couldn’t find Document with ID=2):

app/controllers/documents_controller.rb:30:in `update’