diff options
Diffstat (limited to 'activerecord/lib/active_record')
-rwxr-xr-x | activerecord/lib/active_record/base.rb | 122 | ||||
-rw-r--r-- | activerecord/lib/active_record/calculations.rb | 24 | ||||
-rw-r--r-- | activerecord/lib/active_record/callbacks.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/locale/en.yml | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/named_scope.rb | 2 |
5 files changed, 93 insertions, 59 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index cca012ed55..ebc0b7783f 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -327,7 +327,7 @@ module ActiveRecord #:nodoc: # User.find(user.id).preferences # => { "background" => "black", "display" => large } # # You can also specify a class option as the second parameter that'll raise an exception if a serialized object is retrieved as a - # descendent of a class not in the hierarchy. Example: + # descendant of a class not in the hierarchy. Example: # # class User < ActiveRecord::Base # serialize :preferences, Hash @@ -544,8 +544,9 @@ module ActiveRecord #:nodoc: # * <tt>:having</tt> - Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns. Uses the <tt>HAVING</tt> SQL-clause. # * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned. # * <tt>:offset</tt> - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4. - # * <tt>:joins</tt> - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed) - # or named associations in the same form used for the <tt>:include</tt> option, which will perform an <tt>INNER JOIN</tt> on the associated table(s). + # * <tt>:joins</tt> - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed), + # named associations in the same form used for the <tt>:include</tt> option, which will perform an <tt>INNER JOIN</tt> on the associated table(s), + # or an array containing a mixture of both strings and named associations. # If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table's columns. # Pass <tt>:readonly => false</tt> to override. # * <tt>:include</tt> - Names associations that should be loaded alongside. The symbols named refer @@ -755,25 +756,26 @@ module ActiveRecord #:nodoc: end end - # Delete an object (or multiple objects) where the +id+ given matches the primary_key. A SQL +DELETE+ command - # 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. + # Deletes the row with a primary key matching the +id+ argument, using a + # SQL +DELETE+ statement, and returns the number of rows deleted. Active + # Record objects are not instantiated, so the object's callbacks are not + # executed, including any <tt>:dependent</tt> association options or + # Observer methods. # - # Objects are _not_ instantiated with this method, and so +:dependent+ rules - # defined on associations are not honered. + # You can delete multiple rows at once by passing an Array of <tt>id</tt>s. # - # ==== Parameters - # - # * +id+ - Can be either an Integer or an Array of Integers. + # Note: Although it is often much faster than the alternative, + # <tt>#destroy</tt>, skipping callbacks might bypass business logic in + # your application that ensures referential integrity or performs other + # essential jobs. # # ==== Examples # - # # Delete a single object + # # Delete a single row # Todo.delete(1) # - # # Delete multiple objects - # todos = [1,2,3] - # Todo.delete(todos) + # # Delete multiple rows + # Todo.delete([2,3,4]) def delete(id) delete_all([ "#{connection.quote_column_name(primary_key)} IN (?)", id ]) end @@ -849,25 +851,32 @@ module ActiveRecord #:nodoc: connection.update(sql, "#{name} Update") end - # Destroys the records matching +conditions+ by instantiating each record and calling their +destroy+ method. - # This means at least 2*N database queries to destroy N records, so avoid +destroy_all+ if you are deleting - # many records. If you want to simply delete records without worrying about dependent associations or - # callbacks, use the much faster +delete_all+ method instead. + # Destroys the records matching +conditions+ by instantiating each + # record and calling its +destroy+ method. Each object's callbacks are + # executed (including <tt>:dependent</tt> association options and + # +before_destroy+/+after_destroy+ Observer methods). Returns the + # collection of objects that were destroyed; each will be frozen, to + # reflect that no changes should be made (since they can't be + # persisted). + # + # Note: Instantiation, callback execution, and deletion of each + # record can be time consuming when you're removing many records at + # once. It generates at least one SQL +DELETE+ query per record (or + # possibly more, to enforce your callbacks). If you want to delete many + # rows quickly, without concern for their associations or callbacks, use + # +delete_all+ instead. # # ==== Parameters # - # * +conditions+ - Conditions are specified the same way as with +find+ method. + # * +conditions+ - A string, array, or hash that specifies which records + # to destroy. If omitted, all records are destroyed. See the + # Conditions section in the introduction to ActiveRecord::Base for + # more information. # - # ==== Example + # ==== Examples # # 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) + # Person.destroy_all(:status => "inactive") def destroy_all(conditions = nil) find(:all, :conditions => conditions).each { |object| object.destroy } end @@ -1802,15 +1811,13 @@ module ActiveRecord #:nodoc: table_name end - # Enables dynamic finders like find_by_user_name(user_name) and find_by_user_name_and_password(user_name, password) that are turned into - # find(:first, :conditions => ["user_name = ?", user_name]) and find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password]) - # respectively. Also works for find(:all) by using find_all_by_amount(50) that is turned into find(:all, :conditions => ["amount = ?", 50]). - # - # It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount - # is actually find_all_by_amount(amount, options). + # Enables dynamic finders like <tt>find_by_user_name(user_name)</tt> and <tt>find_by_user_name_and_password(user_name, password)</tt> + # that are turned into <tt>find(:first, :conditions => ["user_name = ?", user_name])</tt> and + # <tt>find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password])</tt> respectively. Also works for + # <tt>find(:all)</tt> by using <tt>find_all_by_amount(50)</tt> that is turned into <tt>find(:all, :conditions => ["amount = ?", 50])</tt>. # - # This also enables you to initialize a record if it is not found, such as find_or_initialize_by_amount(amount) - # or find_or_create_by_user_and_password(user, password). + # It's even possible to use all the additional parameters to +find+. For example, the full interface for +find_all_by_amount+ + # is actually <tt>find_all_by_amount(amount, options)</tt>. # # Also enables dynamic scopes like scoped_by_user_name(user_name) and scoped_by_user_name_and_password(user_name, password) that # are turned into scoped(:conditions => ["user_name = ?", user_name]) and scoped(:conditions => ["user_name = ? AND password = ?", user_name, password]) @@ -2032,7 +2039,11 @@ module ActiveRecord #:nodoc: # end # # In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of - # <tt>:conditions</tt> and <tt>:include</tt> options in <tt>:find</tt>, which are merged. + # <tt>:conditions</tt>, <tt>:include</tt>, and <tt>:joins</tt> options in <tt>:find</tt>, which are merged. + # + # <tt>:joins</tt> options are uniqued so multiple scopes can join in the same table without table aliasing + # problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the + # array of strings format for your joins. # # class Article < ActiveRecord::Base # def self.find_with_scope @@ -2156,7 +2167,7 @@ module ActiveRecord #:nodoc: scoped_methods.last end - # Returns the class type of the record using the current module as a prefix. So descendents of + # Returns the class type of the record using the current module as a prefix. So descendants of # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass. def compute_type(type_name) modularized_name = type_name_with_module(type_name) @@ -2169,7 +2180,8 @@ module ActiveRecord #:nodoc: end end - # Returns the class descending directly from Active Record in the inheritance hierarchy. + # Returns the class descending directly from ActiveRecord::Base or an + # abstract class, if any, in the inheritance hierarchy. def class_of_active_record_descendant(klass) if klass.superclass == Base || klass.superclass.abstract_class? klass @@ -2518,14 +2530,16 @@ module ActiveRecord #:nodoc: create_or_update || raise(RecordNotSaved) end - # Deletes the record in the database and freezes this instance to reflect that no changes should - # be made (since they can't be persisted). + # Deletes the record in the database and freezes this instance to + # reflect that no changes should be made (since they can't be + # persisted). Returns the frozen instance. # - # Unlike #destroy, this method doesn't run any +before_delete+ and +after_delete+ - # callbacks, nor will it enforce any association +:dependent+ rules. - # - # In addition to deleting this record, any defined +before_delete+ and +after_delete+ - # callbacks are run, and +:dependent+ rules defined on associations are run. + # The row is simply removed with a SQL +DELETE+ statement on the + # record's primary key, and no callbacks are executed. + # + # To enforce the object's +before_destroy+ and +after_destroy+ + # callbacks, Observer methods, or any <tt>:dependent</tt> association + # options, use <tt>#destroy</tt>. def delete self.class.delete(id) unless new_record? freeze @@ -2726,7 +2740,19 @@ module ActiveRecord #:nodoc: end end - # Format attributes nicely for inspect. + # Returns an <tt>#inspect</tt>-like string for the value of the + # attribute +attr_name+. String attributes are elided after 50 + # characters, and Date and Time attributes are returned in the + # <tt>:db</tt> format. Other attributes return the value of + # <tt>#inspect</tt> without modification. + # + # person = Person.create!(:name => "David Heinemeier Hansson " * 3) + # + # person.attribute_for_inspect(:name) + # # => '"David Heinemeier Hansson David Heinemeier Hansson D..."' + # + # person.attribute_for_inspect(:created_at) + # # => '"2009-01-12 04:48:57"' def attribute_for_inspect(attr_name) value = read_attribute(attr_name) @@ -2855,7 +2881,7 @@ module ActiveRecord #:nodoc: id end - # Sets the attribute used for single table inheritance to this class name if this is not the ActiveRecord::Base descendent. + # Sets the attribute used for single table inheritance to this class name if this is not the ActiveRecord::Base descendant. # Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to do Reply.new without having to # set <tt>Reply[Reply.inheritance_column] = "Reply"</tt> yourself. No such attribute would be set for objects of the # Message class in that example. diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb index 65512d534a..b239c03284 100644 --- a/activerecord/lib/active_record/calculations.rb +++ b/activerecord/lib/active_record/calculations.rb @@ -48,30 +48,38 @@ module ActiveRecord calculate(:count, *construct_count_options_from_args(*args)) end - # Calculates the average value on a given column. The value is returned as a float. See +calculate+ for examples with options. + # Calculates the average value on a given column. The value is returned as + # a float, or +nil+ if there's no row. See +calculate+ for examples with + # options. # - # Person.average('age') + # Person.average('age') # => 35.8 def average(column_name, options = {}) calculate(:avg, column_name, options) end - # Calculates the minimum value on a given column. The value is returned with the same data type of the column. See +calculate+ for examples with options. + # Calculates the minimum value on a given column. The value is returned + # with the same data type of the column, or +nil+ if there's no row. See + # +calculate+ for examples with options. # - # Person.minimum('age') + # Person.minimum('age') # => 7 def minimum(column_name, options = {}) calculate(:min, column_name, options) end - # Calculates the maximum value on a given column. The value is returned with the same data type of the column. See +calculate+ for examples with options. + # Calculates the maximum value on a given column. The value is returned + # with the same data type of the column, or +nil+ if there's no row. See + # +calculate+ for examples with options. # - # Person.maximum('age') + # Person.maximum('age') # => 93 def maximum(column_name, options = {}) calculate(:max, column_name, options) end - # Calculates the sum of values on a given column. The value is returned with the same data type of the column. See +calculate+ for examples with options. + # Calculates the sum of values on a given column. The value is returned + # with the same data type of the column, 0 if there's no row. See + # +calculate+ for examples with options. # - # Person.sum('age') + # Person.sum('age') # => 4562 def sum(column_name, options = {}) calculate(:sum, column_name, options) end diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 9f5384d39a..88958f4583 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -77,7 +77,7 @@ module ActiveRecord # # In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+. So, use the callback macros when # you want to ensure that a certain callback is called for the entire hierarchy, and use the regular overwriteable methods - # when you want to leave it up to each descendent to decide whether they want to call +super+ and trigger the inherited callbacks. + # when you want to leave it up to each descendant to decide whether they want to call +super+ and trigger the inherited callbacks. # # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the callbacks before specifying the # associations. Otherwise, you might trigger the loading of a child before the parent has registered the callbacks and they won't diff --git a/activerecord/lib/active_record/locale/en.yml b/activerecord/lib/active_record/locale/en.yml index 7e205435f7..bf8a71d236 100644 --- a/activerecord/lib/active_record/locale/en.yml +++ b/activerecord/lib/active_record/locale/en.yml @@ -37,7 +37,7 @@ en: # blank: "This is a custom blank message for User login" # Will define custom blank validation message for User model and # custom blank validation message for login attribute of User model. - models: + #models: # Translate model names. Used in Model.human_name(). #models: diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 83043c2c22..989b2a1ec5 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -39,7 +39,7 @@ module ActiveRecord # Nested finds and calculations also work with these compositions: <tt>Shirt.red.dry_clean_only.count</tt> returns the number of garments # for which these criteria obtain. Similarly with <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>. # - # All \scopes are available as class methods on the ActiveRecord::Base descendent upon which the \scopes were defined. But they are also available to + # All \scopes are available as class methods on the ActiveRecord::Base descendant upon which the \scopes were defined. But they are also available to # <tt>has_many</tt> associations. If, # # class Person < ActiveRecord::Base |