diff options
-rw-r--r-- | activerecord/lib/active_record/associations.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/active_record/autosave_association.rb | 79 |
2 files changed, 23 insertions, 59 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index cf75d2dc9b..8be36482d4 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -957,8 +957,7 @@ module ActiveRecord # If false, don't validate the associated objects when saving the parent object. true by default. # [:autosave] # If true, always save the associated objects or destroy them if marked for destruction, - # when saving the parent object. - # If false, never save or destroy the associated objects. + # when saving the parent object. If false, never save or destroy the associated objects. # By default, only save associated objects that are new records. # [:inverse_of] # Specifies the name of the <tt>belongs_to</tt> association on the associated object diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index dc6352ab12..131591405c 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -3,13 +3,13 @@ require 'active_support/core_ext/array/wrap' module ActiveRecord # = Active Record Autosave Association # - # AutosaveAssociation is a module that takes care of automatically saving - # associacted records when parent is saved. In addition to saving, it + # +AutosaveAssociation+ is a module that takes care of automatically saving + # associacted records when their parent is saved. In addition to saving, it # also destroys any associated records that were marked for destruction. - # (See mark_for_destruction and marked_for_destruction?) + # (See +mark_for_destruction+ and <tt>marked_for_destruction?</tt>). # # Saving of the parent, its associations, and the destruction of marked - # associations, all happen inside 1 transaction. This should never leave the + # associations, all happen inside a transaction. This should never leave the # database in an inconsistent state. # # If validations for any of the associations fail, their error messages will @@ -18,9 +18,8 @@ module ActiveRecord # Note that it also means that associations marked for destruction won't # be destroyed directly. They will however still be marked for destruction. # - # Do note that <tt>:autosave => false</tt> is not same as not declaring <tt>:autosave</tt> - # option. When <tt>:autosave</tt> option is not declared then it works in - # theoreticall <tt>:new_only</tt> mode. Look at has_many example discused below for details. + # Note that <tt>:autosave => false</tt> is not same as not declaring <tt>:autosave</tt>. + # When the <tt>:autosave</tt> option is not present new associations are saved. # # === One-to-one Example # @@ -32,7 +31,7 @@ module ActiveRecord # automatically _and_ atomically: # # post = Post.find(1) - # post.title # => "The current global position of migrating ducks" + # post.title # => "The current global position of migrating ducks" # post.author.name # => "alloy" # # post.title = "On the migration of ducks" @@ -40,7 +39,7 @@ module ActiveRecord # # post.save # post.reload - # post.title # => "On the migration of ducks" + # post.title # => "On the migration of ducks" # post.author.name # => "Eloy Duran" # # Destroying an associated model, as part of the parent's save action, is as @@ -50,6 +49,7 @@ module ActiveRecord # post.author.marked_for_destruction? # => true # # Note that the model is _not_ yet removed from the database: + # # id = post.author.id # Author.find_by_id(id).nil? # => false # @@ -57,14 +57,12 @@ module ActiveRecord # post.reload.author # => nil # # Now it _is_ removed from the database: + # # Author.find_by_id(id).nil? # => true # # === One-to-many Example # - # When <tt>autosave</tt> is not declared then also children will get saved when parent is saved - # in certain conditions. - # - # Consider a Post model with many Comments: + # When <tt>:autosave</tt> is not declared new children are saved when their parent is saved: # # class Post # has_many :comments # :autosave option is no declared @@ -72,43 +70,36 @@ module ActiveRecord # # post = Post.new(:title => 'ruby rocks') # post.comments.build(:body => 'hello world') - # post.save # => will save both post and comment + # post.save # => saves both post and comment # # post = Post.create(:title => 'ruby rocks') # post.comments.build(:body => 'hello world') - # post.save # => will save both post and comment + # post.save # => saves both post and comment # # post = Post.create(:title => 'ruby rocks') # post.comments.create(:body => 'hello world') - # post.save # => will save both post and comment - # - # post = Post.create(:title => 'ruby rocks') - # post.comments.build(:body => 'hello world') - # post.comments[0].body = 'hi everyone' - # post.save # => will save both post and comment and comment will have 'hi everyone' + # post.save # => saves both post and comment # - # In the above cases even without <tt>autosave</tt> option children got updated. + # When <tt>:autosave</tt> is true all children is saved, no matter whether they are new records: # # class Post # has_many :comments, :autosave => true # end # - # <tt>:autosave</tt> declaration is required if an attempt is made to change an existing - # associatin in memory. - # # post = Post.create(:title => 'ruby rocks') # post.comments.create(:body => 'hello world') # post.comments[0].body = 'hi everyone' - # post.save # => will save both post and comment and comment will have 'hi everyone' + # post.save # => saves both post and comment, with 'hi everyone' as title # - # Destroying one of the associated models members, as part of the parent's - # save action, is as simple as marking it for destruction: + # Destroying one of the associated models as part of the parent's save action + # is as simple as marking it for destruction: # # post.comments.last.mark_for_destruction # post.comments.last.marked_for_destruction? # => true # post.comments.length # => 2 # # Note that the model is _not_ yet removed from the database: + # # id = post.comments.last.id # Comment.find_by_id(id).nil? # => false # @@ -116,39 +107,13 @@ module ActiveRecord # post.reload.comments.length # => 1 # # Now it _is_ removed from the database: + # # Comment.find_by_id(id).nil? # => true # # === Validation # - # Validation is performed on the parent as usual, but also on all autosave - # enabled associations. If any of the associations fail validation, its - # error messages will be applied on the parents errors object and validation - # of the parent will fail. - # - # Consider a Post model with Author which validates the presence of its name - # attribute: - # - # class Post - # has_one :author, :autosave => true - # end - # - # class Author - # validates_presence_of :name - # end - # - # post = Post.find(1) - # post.author.name = '' - # post.save # => false - # post.errors # => #<ActiveRecord::Errors:0x174498c @errors={"author.name"=>["can't be blank"]}, @base=#<Post ...>> - # - # No validations will be performed on the associated models when validations - # are skipped for the parent: - # - # post = Post.find(1) - # post.author.name = '' - # post.save(:validate => false) # => true - # - # Note that validation will be perfomend even if <tt>autosave</tt> option is not declared. + # Validations on children records are run or not depending on the <tt>:validate</tt> + # option of the association. module AutosaveAssociation extend ActiveSupport::Concern |