【问题标题】:Save collection of updated records all at once一次保存所有更新记录的集合
【发布时间】:2011-07-09 04:26:46
【问题描述】:

据我了解,build 方法可用于在保存之前建立关联记录的集合。然后,当调用save 时,所有子记录都将被验证并保存,如果验证错误,父记录将有一个错误反映这一点。第一个问题是,这是正确的吗?

但我的主要问题是,假设上述内容有效,是否可以对更新做同样的事情,而不是创建?换句话说,有没有办法更新与父记录关联的集合中的多个记录,然后保存父记录并立即进行所有更新(如果子项中存在验证错误,则父项中会出现错误)?

编辑: 总而言之,我想知道正确的方法来处理需要一次更新和保存父记录和多个关联子记录的情况,并且任何错误都会中止整个保存过程。

【问题讨论】:

  • 只是一个建议。您也可以将代码包装在 ActiveRecord::Transaction 中并使用 .save!而不是保存。如果处理了异常,Activerecord 将回滚任何更改。 api.rubyonrails.org/classes/ActiveRecord/Transactions/…
  • @andrea 这是一个非常有趣的方法。可能对许多事情有用。

标签: ruby-on-rails validation collections build associations


【解决方案1】:

尝试在您的 Patient 类中使用 validates_associated :some_child_records

如果您只想在更新时发生这种情况,只需使用 :on 选项,例如 validates_associated :some_child_records, :on => :update

更多信息在这里:

【讨论】:

    【解决方案2】:

    首先为@andrea +1 Transactions - 我不知道的很酷的东西

    但最简单的方法是使用 accepts_nested_attributes_for method 作为模型。

    让我们举个例子。我们有两个模型:Post title:stringComment body:string post:references

    让我们看看模型:

    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
    

    你看:我们在这里得到了一些验证。所以我们去rails console做一些测试:

    post = Post.new
    post.save
    #=> false
    post.errors
    #=> #<OrderedHash {:title=>["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
    #=> #<OrderedHash {:"comments.body"=>["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
    

    太棒了!一切正常。

    现在让我们用 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
    #=> #<OrderedHash {:"comments.body"=>["can't be blank"]}>
    

    这行得通!

    那么你怎么能使用它。在你的模型中以同样的方式,在像普通表单一样的视图中,但使用 fields_for tag 进行关联。您还可以使用非常深的嵌套来关联验证,它会完美运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多