validation - Rails: Save collection of updated records all at once -
as understand it, build
method can used build collection of associated records before saving. then, when calling save
, child records validated , saved, , if there validation errors parent record have error reflecting this. first question is, correct?
but main question is, assuming above valid, possible same thing updates, not creates? in other words, there way update several records in collection associated parent record, save parent record , have updates take place @ once (with error in parent if there validation errors in children)?
edit: summarize, i'm wondering right way handle case parent record , several associated child records need updated , saved @ once, errors aborting whole save process.
firstly +1 @andrea transactions
- cool stuff didn't know
but easiest way here go use accepts_nested_attributes_for
method model.
lets make example. have got 2 models: post title:string
, comment body:string post:references
lets models:
class post < activerecord::base has_many :comments validates :title, :presence => true accepts_nested_attributes_for :comments # our hero end class comment < activerecord::base belongs_to :post validates :body, :presence => true end
you see: have got validations here. let's go rails console
tests:
post = post.new post.save #=> false post.errors #=> #<orderedhash {:title=>["can't blank"]}> post.title = "my post title" # interesting: adding association # 1 comment ok , second __empty__ body post.comments_attributes = [{:body => "my cooment"}, {:body => nil}] post.save #=> false post.errors #=> #<orderedhash {:"comments.body"=>["can't blank"]}> # cool! works fine # let's cleean our comments , add new valid post.comments.destroy_all post.comments_attributes = [{:body => "first comment"}, {:body => "second comment"}] post.save #=> true
great! works fine.
now lets same things update:
post = post.last post.comments.count # have got 2 comments id:1 , id:2 #=> 2 # lets change first comment's body post.comments_attributes = [{:id => 1, :body => "changed body"}] # second comment isn't changed post.save #=> true # let's check validation post.comments_attributes => [{:id => 1, :body => nil}] post.save #=> false post.errors #=> #<orderedhash {:"comments.body"=>["can't blank"]}>
this works!
so how can use it. in models same way, , in views common forms fields_for
tag association. can use deep nesting association validations nd work perfect.
Comments
Post a Comment