首先+1到@andrea爲Transactions
- 很酷的東西,我不知道
但最簡單的華麗在這裏,要去使用accepts_nested_attributes_for
method爲模型。
讓我們舉個例子。我們有兩種型號:Post title:string
和Comment 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
太棒了!一切正常。
現在讓我們用更新做同樣的事情:
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爲關聯的看法。此外,您可以使用非常深的嵌套與您的驗證聯繫在一起,它將起到完美的作用。
只有一個建議。你也可以將你的代碼包裝在ActiveRecord :: Transaction 中,並使用.save!而不是保存。 如果處理異常,Activerecord將回滾任何更改。 http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html – andrea 2011-03-08 11:45:25
@andrea這是一個非常有趣的方法。可能對許多事情有用。 – bowsersenior 2011-03-08 18:09:34