From e98dd5421580d01449ad97a84e00bc2d025248bc Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Sun, 21 Sep 2008 20:57:28 +0200 Subject: In some of ActiveRecord::Base's API documentation, replace 'Attributes' with 'Parameters' because that's more correct. --- activerecord/lib/active_record/base.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 220b8cb866..348c9c41ee 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -512,7 +512,7 @@ module ActiveRecord #:nodoc: # # All approaches accept an options hash as their last parameter. # - # ==== Attributes + # ==== Parameters # # * :conditions - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro. # * :order - An SQL fragment like "created_at DESC, name". @@ -697,7 +697,7 @@ module ActiveRecord #:nodoc: # Updates an object (or multiple objects) and saves it to the database, if validations pass. # The resulting object is returned whether the object was saved successfully to the database or not. # - # ==== Attributes + # ==== Parameters # # * +id+ - This should be the id or an array of ids to be updated. # * +attributes+ - This should be a Hash of attributes to be set on the object, or an array of Hashes. @@ -727,7 +727,7 @@ module ActiveRecord #:nodoc: # # Objects are _not_ instantiated with this method. # - # ==== Attributes + # ==== Parameters # # * +id+ - Can be either an Integer or an Array of Integers. # @@ -750,7 +750,7 @@ module ActiveRecord #:nodoc: # This essentially finds the object (or multiple objects) with the given id, creates a new object # from the attributes, and then calls destroy on it. # - # ==== Attributes + # ==== Parameters # # * +id+ - Can be either an Integer or an Array of Integers. # @@ -774,7 +774,7 @@ module ActiveRecord #:nodoc: # also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the # database. It does not instantiate the involved models and it does not trigger Active Record callbacks. # - # ==== Attributes + # ==== Parameters # # * +updates+ - A string of column and value pairs that will be set on any records that match conditions. # What goes into the SET clause. @@ -820,7 +820,7 @@ module ActiveRecord #:nodoc: # many records. If you want to simply delete records without worrying about dependent associations or # callbacks, use the much faster +delete_all+ method instead. # - # ==== Attributes + # ==== Parameters # # * +conditions+ - Conditions are specified the same way as with +find+ method. # @@ -839,7 +839,7 @@ module ActiveRecord #:nodoc: # goes straight to the database, much more efficient than +destroy_all+. Careful with relations # though, in particular :dependent is not taken into account. # - # ==== Attributes + # ==== Parameters # # * +conditions+ - Conditions are specified the same way as with +find+ method. # @@ -859,7 +859,7 @@ module ActiveRecord #:nodoc: # The use of this method should be restricted to complicated SQL queries that can't be executed # using the ActiveRecord::Calculations class methods. Look into those before using this. # - # ==== Attributes + # ==== Parameters # # * +sql+ - An SQL statement which should return a count query from the database, see the example below. # @@ -877,7 +877,7 @@ module ActiveRecord #:nodoc: # with the given ID, altering the given hash of counters by the amount # given by the corresponding value: # - # ==== Attributes + # ==== Parameters # # * +id+ - The id of the object you wish to update a counter on. # * +counters+ - An Array of Hashes containing the names of the fields @@ -907,7 +907,7 @@ module ActiveRecord #:nodoc: # For example, a DiscussionBoard may cache post_count and comment_count otherwise every time the board is # shown it would have to run an SQL query to find how many posts and comments there are. # - # ==== Attributes + # ==== Parameters # # * +counter_name+ - The name of the field that should be incremented. # * +id+ - The id of the object that should be incremented. @@ -924,7 +924,7 @@ module ActiveRecord #:nodoc: # # This works the same as increment_counter but reduces the column value by 1 instead of increasing it. # - # ==== Attributes + # ==== Parameters # # * +counter_name+ - The name of the field that should be decremented. # * +id+ - The id of the object that should be decremented. @@ -1019,7 +1019,7 @@ module ActiveRecord #:nodoc: # The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that # class on retrieval or SerializationTypeMismatch will be raised. # - # ==== Attributes + # ==== Parameters # # * +attr_name+ - The field name that should be serialized. # * +class_name+ - Optional, class name that the object type should be equal to. -- cgit v1.2.3 From 6547e6897cb07f73f05c13eef3bd6d211ec6dafd Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Sun, 21 Sep 2008 20:59:33 +0200 Subject: Improve various examples and API description texts. --- activerecord/lib/active_record/base.rb | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 348c9c41ee..13393ce6a9 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -725,7 +725,8 @@ module ActiveRecord #:nodoc: # is executed on the database which means that no callbacks are fired off running this. This is an efficient method # of deleting records that don't need cleaning up after or other actions to be taken. # - # Objects are _not_ instantiated with this method. + # Objects are _not_ instantiated with this method, and so +:dependent+ rules + # defined on associations are not honered. # # ==== Parameters # @@ -826,18 +827,22 @@ module ActiveRecord #:nodoc: # # ==== Example # - # Person.destroy_all "last_login < '2004-04-04'" + # Person.destroy_all("last_login < '2004-04-04'") # # This loads and destroys each person one by one, including its dependent associations and before_ and # after_destroy callbacks. + # + # +conditions+ can be anything that +find+ also accepts: + # + # Person.destroy_all(:last_login => 6.hours.ago) def destroy_all(conditions = nil) find(:all, :conditions => conditions).each { |object| object.destroy } end # Deletes the records matching +conditions+ without instantiating the records first, and hence not # calling the +destroy+ method nor invoking callbacks. This is a single SQL DELETE statement that - # goes straight to the database, much more efficient than +destroy_all+. Careful with relations - # though, in particular :dependent is not taken into account. + # goes straight to the database, much more efficient than +destroy_all+. Be careful with relations + # though, in particular :dependent rules defined on associations are not honored. # # ==== Parameters # @@ -845,9 +850,10 @@ module ActiveRecord #:nodoc: # # ==== Example # - # Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')" + # Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')") + # Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else']) # - # This deletes the affected posts all at once with a single DELETE statement. If you need to destroy dependent + # Both calls delete the affected posts all at once with a single DELETE statement. If you need to destroy dependent # associations or call your before_* or +after_destroy+ callbacks, use the +destroy_all+ method instead. def delete_all(conditions = nil) sql = "DELETE FROM #{quoted_table_name} " @@ -1927,6 +1933,9 @@ module ActiveRecord #:nodoc: # end # end # end + # + # *Note*: the +:find+ scope also has effect on update and deletion methods, + # like +update_all+ and +delete_all+. def with_scope(method_scoping = {}, action = :merge, &block) method_scoping = method_scoping.method_scoping if method_scoping.respond_to?(:method_scoping) -- cgit v1.2.3 From 353dc9d389f5d62c320c17eb9c7bb1acfc480952 Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Sun, 21 Sep 2008 21:00:16 +0200 Subject: Document some of the internals of associations handling. --- activerecord/lib/active_record/associations.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 5d91315aad..33457822ff 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1452,6 +1452,8 @@ module ActiveRecord end end + # Creates before_destroy callback methods that nullify, delete or destroy + # has_one associated objects, according to the defined :dependent rule. def configure_dependency_for_has_one(reflection) if reflection.options.include?(:dependent) case reflection.options[:dependent] @@ -1465,6 +1467,10 @@ module ActiveRecord when :delete method_name = "has_one_dependent_delete_for_#{reflection.name}".to_sym define_method(method_name) do + # Retrieve the associated object and delete it. The retrieval + # is necessary because there may be multiple associated objects + # with foreign keys pointing to this object, and we only want + # to delete the correct one, not all of them. association = send(reflection.name) association.class.delete(association.id) unless association.nil? end -- cgit v1.2.3 From 7da89e9ae74b5f549c286f68c2fc2faba4958270 Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Sun, 21 Sep 2008 22:39:17 +0200 Subject: In ActiveRecord::Base#destroy's documention, also mention that before/after_delete callbacks and :dependent callbacks are run. --- activerecord/lib/active_record/base.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 13393ce6a9..fa406a82b1 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2386,6 +2386,9 @@ module ActiveRecord #:nodoc: # Deletes the record in the database and freezes this instance to reflect that no changes should # be made (since they can't be persisted). + # + # In addition to deleting this record, any defined +before_delete+ and +after_delete+ + # callbacks are run, and +:dependent+ rules defined on associations are run. def destroy unless new_record? connection.delete <<-end_sql, "#{self.class.name} Destroy" -- cgit v1.2.3 From c1525e8bb08d82a397e535dc3707ab3c370e3764 Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Mon, 22 Sep 2008 00:29:37 +0200 Subject: Improve documentation for attributes= and document its 'guard_protected_attributes' parameter. --- activerecord/lib/active_record/base.rb | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index fa406a82b1..c0c9b8a9b3 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2526,10 +2526,25 @@ module ActiveRecord #:nodoc: end # Allows you to set all the attributes at once by passing in a hash with keys - # matching the attribute names (which again matches the column names). Sensitive attributes can be protected - # from this form of mass-assignment by using the +attr_protected+ macro. Or you can alternatively - # specify which attributes *can* be accessed with the +attr_accessible+ macro. Then all the + # matching the attribute names (which again matches the column names). + # + # If +guard_protected_attributes+ is true (the default), then sensitive + # attributes can be protected from this form of mass-assignment by using + # the +attr_protected+ macro. Or you can alternatively specify which + # attributes *can* be accessed with the +attr_accessible+ macro. Then all the # attributes not included in that won't be allowed to be mass-assigned. + # + # class User < ActiveRecord::Base + # attr_protected :is_admin + # end + # + # user = User.new + # user.attributes = { :username => 'Phusion', :is_admin => true } + # user.username # => "Phusion" + # user.is_admin? # => false + # + # user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false) + # user.is_admin? # => true def attributes=(new_attributes, guard_protected_attributes = true) return if new_attributes.nil? attributes = new_attributes.dup -- cgit v1.2.3 From 63c7dcfeaac680d6596b72f1619e74f89e538ed4 Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Mon, 22 Sep 2008 10:16:06 +0200 Subject: Change 'racing condition' to 'race condition'. --- activerecord/lib/active_record/validations.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 73d9b36fc2..8481706074 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -642,7 +642,7 @@ module ActiveRecord # # Using this validation method in conjunction with ActiveRecord::Base#save # does not guarantee the absence of duplicate record insertions, because - # uniqueness checks on the application level are inherently prone to racing + # uniqueness checks on the application level are inherently prone to race # conditions. For example, suppose that two users try to post a Comment at # the same time, and a Comment's title must be unique. At the database-level, # the actions performed by these users could be interleaved in the following manner: @@ -685,7 +685,7 @@ module ActiveRecord # do that efficiently), and thus not recommended. # - Creating a unique index on the field, by using # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the - # rare case that a racing condition occurs, the database will guarantee + # rare case that a race condition occurs, the database will guarantee # the field's uniqueness. # # When the database catches such a duplicate insertion, -- cgit v1.2.3