Save collection of updated records all at once

前端 未结 2 678
花落未央
花落未央 2021-01-04 22:50

As I understand it, the build method can be used to build up a collection of associated records before saving. Then, when calling save, all the chi

2条回答
  •  借酒劲吻你
    2021-01-04 23:13

    Firstly +1 to @andrea for Transactions - cool stuff I didn't know

    But easiest way here to go is to use accepts_nested_attributes_for method for model.

    Lets make an example. We have got two models: Post title:string and Comment body:string post:references

    lets look into models:

    class Post < ActiveRecord::Base
      has_many :comments
      validates :title, :presence => true
      accepts_nested_attributes_for :comments # this is our hero
    end
    
    class Comment < ActiveRecord::Base
      belongs_to :post
      validates :body, :presence => true
    end
    

    You see: we have got some validations here. So let's go to rails console to do some tests:

    post = Post.new
    post.save
    #=> false
    post.errors
    #=> #["can't be blank"]}>
    post.title = "My post title"
    # now the interesting: adding association
    # one comment is ok and second with __empty__ body
    post.comments_attributes = [{:body => "My cooment"}, {:body => nil}]
    post.save
    #=> false
    post.errors
    #=> #["can't be blank"]}>
    # Cool! everything works fine
    # let's now cleean our comments and add some new valid
    post.comments.destroy_all
    post.comments_attributes = [{:body => "first comment"}, {:body => "second comment"}]
    post.save
    #=> true
    

    Great! All works fine.

    Now lets do the same things with update:

    post = Post.last
    post.comments.count # We have got already two comments with ID:1 and 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
    # Now let's check validation
    post.comments_attributes => [{:id => 1, :body => nil}]
    post.save
    #=> false
    post.errors
    #=> #["can't be blank"]}>
    

    This works!

    SO how can you use it. In your models the same way, and in views like common forms but with fields_for tag for association. Also you can use very deep nesting for your association with validations nd it will work perfect.

提交回复
热议问题