From 4308d871b670d8a0f0d112624a72a8836e032145 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 7 May 2008 23:09:13 +0200 Subject: several fixes and conventions revision in AR associations docs --- activerecord/lib/active_record/associations.rb | 221 +++++++++++++------------ 1 file changed, 111 insertions(+), 110 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 691d938788..fb5f1f8a8c 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -110,7 +110,7 @@ module ActiveRecord # # Don't create associations that have the same name as instance methods of ActiveRecord::Base. Since the association # adds a method with that name to its model, it will override the inherited method and break things. - # For instance, #attributes and #connection would be bad choices for association names. + # For instance, +attributes+ and +connection+ would be bad choices for association names. # # == Auto-generated methods # @@ -258,7 +258,7 @@ module ActiveRecord # order to update their primary keys - except if the parent object is unsaved (new_record? == true). # * If either of these saves fail (due to one of the objects being invalid) the assignment statement returns +false+ and the assignment # is cancelled. - # * If you wish to assign an object to a +has_one+ association without saving it, use the #association.build method (documented below). + # * If you wish to assign an object to a +has_one+ association without saving it, use the association.build method (documented below). # * Assigning an object to a +belongs_to+ association does not save the object, since the foreign key field belongs on the parent. It # does not save the parent either. # @@ -266,8 +266,8 @@ module ActiveRecord # # * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically saves that object, except if the parent object # (the owner of the collection) is not yet stored in the database. - # * If saving any of the objects being added to a collection (via #push or similar) fails, then #push returns +false+. - # * You can add an object to a collection without automatically saving it by using the #collection.build method (documented below). + # * If saving any of the objects being added to a collection (via push or similar) fails, then push returns +false+. + # * You can add an object to a collection without automatically saving it by using the collection.build method (documented below). # * All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved. # # === Association callbacks @@ -504,8 +504,8 @@ module ActiveRecord # # Address.find(:all, :include => :addressable) # INVALID # - # will raise ActiveRecord::EagerLoadPolymorphicError. The reason is that the parent model's type - # is a column value so its corresponding table name cannot be put in the FROM/JOIN clauses of that early query. + # will raise ActiveRecord::EagerLoadPolymorphicError. The reason is that the parent model's type + # is a column value so its corresponding table name cannot be put in the +FROM+/+JOIN+ clauses of that early query. # # In versions greater than 2.0.2 eager loading in polymorphic associations is supported # thanks to a change in the overall preloading strategy. @@ -575,7 +575,7 @@ module ActiveRecord # end # end # - # When Firm#clients is called, it will in turn call MyApplication::Business::Company.find(firm.id). If you want to associate + # When Firm#clients is called, it will in turn call MyApplication::Business::Company.find(firm.id). If you want to associate # with a class in another module scope, this can be done by specifying the complete class name. Example: # # module MyApplication @@ -603,28 +603,28 @@ module ActiveRecord # Adds the following methods for retrieval and query of collections of associated objects: # +collection+ is replaced with the symbol passed as the first argument, so # has_many :clients would add among others clients.empty?. - # * collection(force_reload = false) - returns an array of all the associated objects. + # * collection(force_reload = false) - Returns an array of all the associated objects. # An empty array is returned if none are found. - # * collection<<(object, ...) - adds one or more objects to the collection by setting their foreign keys to the collection's primary key. - # * collection.delete(object, ...) - removes one or more objects from the collection by setting their foreign keys to NULL. + # * collection<<(object, ...) - Adds one or more objects to the collection by setting their foreign keys to the collection's primary key. + # * collection.delete(object, ...) - Removes one or more objects from the collection by setting their foreign keys to +NULL+. # This will also destroy the objects if they're declared as +belongs_to+ and dependent on this model. - # * collection=objects - replaces the collections content by deleting and adding objects as appropriate. - # * collection_singular_ids - returns an array of the associated objects' ids - # * collection_singular_ids=ids - replace the collection with the objects identified by the primary keys in +ids+ - # * collection.clear - removes every object from the collection. This destroys the associated objects if they + # * collection=objects - Replaces the collections content by deleting and adding objects as appropriate. + # * collection_singular_ids - Returns an array of the associated objects' ids + # * collection_singular_ids=ids - Replace the collection with the objects identified by the primary keys in +ids+ + # * collection.clear - Removes every object from the collection. This destroys the associated objects if they # are associated with :dependent => :destroy, deletes them directly from the database if :dependent => :delete_all, - # otherwise sets their foreign keys to NULL. - # * collection.empty? - returns +true+ if there are no associated objects. - # * collection.size - returns the number of associated objects. - # * collection.find - finds an associated object according to the same rules as Base.find. - # * collection.build(attributes = {}, ...) - returns one or more new objects of the collection type that have been instantiated + # otherwise sets their foreign keys to +NULL+. + # * collection.empty? - Returns +true+ if there are no associated objects. + # * collection.size - Returns the number of associated objects. + # * collection.find - Finds an associated object according to the same rules as Base.find. + # * collection.build(attributes = {}, ...) - Returns one or more new objects of the collection type that have been instantiated # with +attributes+ and linked to this object through a foreign key, but have not yet been saved. *Note:* This only works if an # associated object already exists, not if it's +nil+! - # * collection.create(attributes = {}) - returns a new object of the collection type that has been instantiated + # * collection.create(attributes = {}) - Returns a new object of the collection type that has been instantiated # with +attributes+, linked to this object through a foreign key, and that has already been saved (if it passed the validation). # *Note:* This only works if an associated object already exists, not if it's +nil+! # - # Example: A +Firm+ class declares has_many :clients, which will add: + # Example: A Firm class declares has_many :clients, which will add: # * Firm#clients (similar to Clients.find :all, :conditions => "firm_id = #{id}") # * Firm#clients<< # * Firm#clients.delete @@ -650,8 +650,8 @@ module ActiveRecord # * :order - Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, # such as last_name, first_name DESC. # * :foreign_key - Specify the foreign key used for the association. By default this is guessed to be the name - # of this class in lower-case and +_id+ suffixed. So a Person class that makes a +has_many+ association will use +person_id+ - # as the default +foreign_key+. + # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+ association will use "person_id" + # as the default :foreign_key. # * :dependent - If set to :destroy all the associated objects are destroyed # alongside this object by calling their +destroy+ method. If set to :delete_all all associated # objects are deleted *without* calling their +destroy+ method. If set to :nullify all associated @@ -712,14 +712,14 @@ module ActiveRecord # Adds the following methods for retrieval and query of a single associated object: # +association+ is replaced with the symbol passed as the first argument, so # has_one :manager would add among others manager.nil?. - # * association(force_reload = false) - returns the associated object. +nil+ is returned if none is found. - # * association=(associate) - assigns the associate object, extracts the primary key, sets it as the foreign key, + # * association(force_reload = false) - Returns the associated object. +nil+ is returned if none is found. + # * association=(associate) - Assigns the associate object, extracts the primary key, sets it as the foreign key, # and saves the associate object. - # * association.nil? - returns +true+ if there is no associated object. - # * build_association(attributes = {}) - returns a new object of the associated type that has been instantiated + # * association.nil? - Returns +true+ if there is no associated object. + # * build_association(attributes = {}) - Returns a new object of the associated type that has been instantiated # with +attributes+ and linked to this object through a foreign key, but has not yet been saved. Note: This ONLY works if # an association already exists. It will NOT work if the association is +nil+. - # * create_association(attributes = {}) - returns a new object of the associated type that has been instantiated + # * create_association(attributes = {}) - Returns a new object of the associated type that has been instantiated # with +attributes+, linked to this object through a foreign key, and that has already been saved (if it passed the validation). # # Example: An Account class declares has_one :beneficiary, which will add: @@ -732,28 +732,28 @@ module ActiveRecord # The declaration can also include an options hash to specialize the behavior of the association. # # Options are: - # * :class_name - specify the class name of the association. Use it only if that name can't be inferred - # from the association name. So has_one :manager will by default be linked to the +Manager+ class, but - # if the real class name is +Person+, you'll have to specify it with this option. - # * :conditions - specify the conditions that the associated object must meet in order to be included as a +WHERE+ + # * :class_name - Specify the class name of the association. Use it only if that name can't be inferred + # from the association name. So has_one :manager will by default be linked to the Manager class, but + # if the real class name is Person, you'll have to specify it with this option. + # * :conditions - Specify the conditions that the associated object must meet in order to be included as a +WHERE+ # SQL fragment, such as rank = 5. - # * :order - specify the order in which the associated objects are returned as an ORDER BY SQL fragment, - # such as last_name, first_name DESC - # * :dependent - if set to :destroy, the associated object is destroyed when this object is. If set to + # * :order - Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, + # such as last_name, first_name DESC. + # * :dependent - If set to :destroy, the associated object is destroyed when this object is. If set to # :delete, the associated object is deleted *without* calling its destroy method. If set to :nullify, the associated # object's foreign key is set to +NULL+. Also, association is assigned. - # * :foreign_key - specify the foreign key used for the association. By default this is guessed to be the name - # of this class in lower-case and +_id+ suffixed. So a +Person+ class that makes a +has_one+ association will use +person_id+ - # as the default +foreign_key+. - # * :include - specify second-order associations that should be eager loaded when this object is loaded. - # * :as: Specifies a polymorphic interface (See #belongs_to). + # * :foreign_key - Specify the foreign key used for the association. By default this is guessed to be the name + # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association will use "person_id" + # as the default :foreign_key. + # * :include - Specify second-order associations that should be eager loaded when this object is loaded. + # * :as - Specifies a polymorphic interface (See belongs_to). # * :through: Specifies a Join Model through which to perform the query. Options for :class_name and :foreign_key # are ignored, as the association uses the source reflection. You can only use a :through query through a # has_one or belongs_to association on the join model. - # * :source: Specifies the source association name used by has_one :through queries. Only use it if the name cannot be + # * :source - Specifies the source association name used by has_one :through queries. Only use it if the name cannot be # inferred from the association. has_one :favorite, :through => :favorites will look for a - # :favorite on +Favorite+, unless a :source is given. - # * :readonly - if set to +true+, the associated object is readonly through the association. + # :favorite on Favorite, unless a :source is given. + # * :readonly - If true, the associated object is readonly through the association. # # Option examples: # has_one :credit_card, :dependent => :destroy # destroys the associated credit card @@ -796,12 +796,12 @@ module ActiveRecord # Adds the following methods for retrieval and query for a single associated object for which this object holds an id: # +association+ is replaced with the symbol passed as the first argument, so # belongs_to :author would add among others author.nil?. - # * association(force_reload = false) - returns the associated object. +nil+ is returned if none is found. - # * association=(associate) - assigns the associate object, extracts the primary key, and sets it as the foreign key. - # * association.nil? - returns +true+ if there is no associated object. - # * build_association(attributes = {}) - returns a new object of the associated type that has been instantiated + # * association(force_reload = false) - Returns the associated object. +nil+ is returned if none is found. + # * association=(associate) - Assigns the associate object, extracts the primary key, and sets it as the foreign key. + # * association.nil? - Returns +true+ if there is no associated object. + # * build_association(attributes = {}) - Returns a new object of the associated type that has been instantiated # with +attributes+ and linked to this object through a foreign key, but has not yet been saved. - # * create_association(attributes = {}) - returns a new object of the associated type that has been instantiated + # * create_association(attributes = {}) - Returns a new object of the associated type that has been instantiated # with +attributes+, linked to this object through a foreign key, and that has already been saved (if it passed the validation). # # Example: A Post class declares belongs_to :author, which will add: @@ -814,34 +814,35 @@ module ActiveRecord # The declaration can also include an options hash to specialize the behavior of the association. # # Options are: - # * :class_name - specify the class name of the association. Use it only if that name can't be inferred - # from the association name. So has_one :author will by default be linked to the +Author+ class, but - # if the real class name is +Person+, you'll have to specify it with this option. - # * :conditions - specify the conditions that the associated object must meet in order to be included as a +WHERE+ + # * :class_name - Specify the class name of the association. Use it only if that name can't be inferred + # from the association name. So has_one :author will by default be linked to the Author class, but + # if the real class name is Person, you'll have to specify it with this option. + # * :conditions - Specify the conditions that the associated object must meet in order to be included as a +WHERE+ # SQL fragment, such as authorized = 1. - # * :order - specify the order in which the associated objects are returned as an ORDER BY SQL fragment, - # such as last_name, first_name DESC - # * :foreign_key - specify the foreign key used for the association. By default this is guessed to be the name - # of the association with an +_id+ suffix. So a class that defines a +belongs_to :person+ association will use +person_id+ as the default +foreign_key+. - # Similarly, +belongs_to :favorite_person, :class_name => "Person"+ will use a foreign key of +favorite_person_id+. - # * :dependent - if set to :destroy, the associated object is destroyed when this object is. If set to + # * :order - Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, + # such as last_name, first_name DESC. + # * :foreign_key - Specify the foreign key used for the association. By default this is guessed to be the name + # of the association with an "_id" suffix. So a class that defines a belongs_to :person association will use + # "person_id" as the default :foreign_key. Similarly, belongs_to :favorite_person, :class_name => "Person" + # will use a foreign key of "favorite_person_id". + # * :dependent - If set to :destroy, the associated object is destroyed when this object is. If set to # :delete, the associated object is deleted *without* calling its destroy method. This option should not be specified when # belongs_to is used in conjunction with a has_many relationship on another class because of the potential to leave # orphaned records behind. - # * :counter_cache - caches the number of belonging objects on the associate class through the use of +increment_counter+ + # * :counter_cache - Caches the number of belonging objects on the associate class through the use of +increment_counter+ # and +decrement_counter+. The counter cache is incremented when an object of this class is created and decremented when it's - # destroyed. This requires that a column named #{table_name}_count (such as +comments_count+ for a belonging +Comment+ class) - # is used on the associate class (such as a +Post+ class). You can also specify a custom counter cache column by providing + # destroyed. This requires that a column named #{table_name}_count (such as +comments_count+ for a belonging Comment class) + # is used on the associate class (such as a Post class). You can also specify a custom counter cache column by providing # a column name instead of a +true+/+false+ value to this option (e.g., :counter_cache => :my_custom_counter.) # When creating a counter cache column, the database statement or migration must specify a default value of 0, failing to do - # this results in a counter with NULL value, which will never increment. - # Note: Specifying a counter_cache will add it to that model's list of readonly attributes using #attr_readonly. - # * :include - specify second-order associations that should be eager loaded when this object is loaded. + # this results in a counter with +NULL+ value, which will never increment. + # Note: Specifying a counter cache will add it to that model's list of readonly attributes using +attr_readonly+. + # * :include - Specify second-order associations that should be eager loaded when this object is loaded. # Not allowed if the association is polymorphic. - # * :polymorphic - specify this association is a polymorphic association by passing +true+. + # * :polymorphic - Specify this association is a polymorphic association by passing +true+. # Note: If you've enabled the counter cache, then you may want to add the counter cache attribute - # to the attr_readonly list in the associated classes (e.g. class Post; attr_readonly :comments_count; end). - # * :readonly - if set to +true+, the associated object is readonly through the association. + # to the +attr_readonly+ list in the associated classes (e.g. class Post; attr_readonly :comments_count; end). + # * :readonly - If true, the associated object is readonly through the association. # # Option examples: # belongs_to :firm, :foreign_key => "client_of" @@ -926,14 +927,14 @@ module ActiveRecord end # Associates two classes via an intermediate join table. Unless the join table is explicitly specified as - # an option, it is guessed using the lexical order of the class names. So a join between +Developer+ and +Project+ - # will give the default join table name of +developers_projects+ because "D" outranks "P". Note that this precedence - # is calculated using the < operator for String. This means that if the strings are of different lengths, + # an option, it is guessed using the lexical order of the class names. So a join between Developer and Project + # will give the default join table name of "developers_projects" because "D" outranks "P". Note that this precedence + # is calculated using the < operator for String. This means that if the strings are of different lengths, # and the strings are equal when compared up to the shortest length, then the longer string is considered of higher - # lexical precedence than the shorter one. For example, one would expect the tables paper_boxes and papers - # to generate a join table name of papers_paper_boxes because of the length of the name paper_boxes, - # but it in fact generates a join table name of paper_boxes_papers. Be aware of this caveat, and use the - # custom join_table option if you need to. + # lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" + # to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", + # but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the + # custom :join_table option if you need to. # # Deprecated: Any additional fields added to the join table will be placed as attributes when pulling records out through # +has_and_belongs_to_many+ associations. Records returned from join tables with additional attributes will be marked as @@ -943,23 +944,23 @@ module ActiveRecord # Adds the following methods for retrieval and query: # +collection+ is replaced with the symbol passed as the first argument, so # has_and_belongs_to_many :categories would add among others categories.empty?. - # * collection(force_reload = false) - returns an array of all the associated objects. + # * collection(force_reload = false) - Returns an array of all the associated objects. # An empty array is returned if none are found. - # * collection<<(object, ...) - adds one or more objects to the collection by creating associations in the join table + # * collection<<(object, ...) - Adds one or more objects to the collection by creating associations in the join table # (collection.push and collection.concat are aliases to this method). - # * collection.delete(object, ...) - removes one or more objects from the collection by removing their associations from the join table. + # * collection.delete(object, ...) - Removes one or more objects from the collection by removing their associations from the join table. # This does not destroy the objects. - # * collection=objects - replaces the collection's content by deleting and adding objects as appropriate. - # * collection_singular_ids - returns an array of the associated objects' ids - # * collection_singular_ids=ids - replace the collection by the objects identified by the primary keys in +ids+ - # * collection.clear - removes every object from the collection. This does not destroy the objects. - # * collection.empty? - returns +true+ if there are no associated objects. - # * collection.size - returns the number of associated objects. - # * collection.find(id) - finds an associated object responding to the +id+ and that + # * collection=objects - Replaces the collection's content by deleting and adding objects as appropriate. + # * collection_singular_ids - Returns an array of the associated objects' ids. + # * collection_singular_ids=ids - Replace the collection by the objects identified by the primary keys in +ids+. + # * collection.clear - Removes every object from the collection. This does not destroy the objects. + # * collection.empty? - Returns +true+ if there are no associated objects. + # * collection.size - Returns the number of associated objects. + # * collection.find(id) - Finds an associated object responding to the +id+ and that # meets the condition that it has to be associated with this object. - # * collection.build(attributes = {}) - returns a new object of the collection type that has been instantiated + # * collection.build(attributes = {}) - Returns a new object of the collection type that has been instantiated # with +attributes+ and linked to this object through the join table, but has not yet been saved. - # * collection.create(attributes = {}) - returns a new object of the collection type that has been instantiated + # * collection.create(attributes = {}) - Returns a new object of the collection type that has been instantiated # with +attributes+, linked to this object through the join table, and that has already been saved (if it passed the validation). # # Example: A Developer class declares has_and_belongs_to_many :projects, which will add: @@ -978,38 +979,38 @@ module ActiveRecord # The declaration may include an options hash to specialize the behavior of the association. # # Options are: - # * :class_name - specify the class name of the association. Use it only if that name can't be inferred + # * :class_name - Specify the class name of the association. Use it only if that name can't be inferred # from the association name. So has_and_belongs_to_many :projects will by default be linked to the - # +Project+ class, but if the real class name is +SuperProject+, you'll have to specify it with this option. - # * :join_table - specify the name of the join table if the default based on lexical order isn't what you want. + # Project class, but if the real class name is SuperProject, you'll have to specify it with this option. + # * :join_table - Specify the name of the join table if the default based on lexical order isn't what you want. # WARNING: If you're overwriting the table name of either class, the +table_name+ method MUST be declared underneath any # +has_and_belongs_to_many+ declaration in order to work. - # * :foreign_key - specify the foreign key used for the association. By default this is guessed to be the name - # of this class in lower-case and +_id+ suffixed. So a +Person+ class that makes a +has_and_belongs_to_many+ association - # will use +person_id+ as the default +foreign_key+. - # * :association_foreign_key - specify the association foreign key used for the association. By default this is - # guessed to be the name of the associated class in lower-case and +_id+ suffixed. So if the associated class is +Project+, - # the +has_and_belongs_to_many+ association will use +project_id+ as the default association +foreign_key+. - # * :conditions - specify the conditions that the associated object must meet in order to be included as a +WHERE+ + # * :foreign_key - Specify the foreign key used for the association. By default this is guessed to be the name + # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_and_belongs_to_many+ association + # will use "person_id" as the default :foreign_key. + # * :association_foreign_key - Specify the association foreign key used for the association. By default this is + # guessed to be the name of the associated class in lower-case and "_id" suffixed. So if the associated class is Project, + # the +has_and_belongs_to_many+ association will use "project_id" as the default :association_foreign_key. + # * :conditions - Specify the conditions that the associated object must meet in order to be included as a +WHERE+ # SQL fragment, such as authorized = 1. Record creations from the association are scoped if a hash is used. # has_many :posts, :conditions => {:published => true} will create published posts with @blog.posts.create # or @blog.posts.build. - # * :order - specify the order in which the associated objects are returned as an ORDER BY SQL fragment, + # * :order - Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, # such as last_name, first_name DESC - # * :uniq - if set to +true+, duplicate associated objects will be ignored by accessors and query methods - # * :finder_sql - overwrite the default generated SQL statement used to fetch the association with a manual statement - # * :delete_sql - overwrite the default generated SQL statement used to remove links between the associated - # classes with a manual statement - # * :insert_sql - overwrite the default generated SQL statement used to add links between the associated classes - # with a manual statement - # * :extend - anonymous module for extending the proxy, see "Association extensions". - # * :include - specify second-order associations that should be eager loaded when the collection is loaded. - # * :group: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause. - # * :limit: An integer determining the limit on the number of rows that should be returned. - # * :offset: An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows. - # * :select: By default, this is * as in SELECT * FROM, but can be changed if, for example, you want to do a join + # * :uniq - If true, duplicate associated objects will be ignored by accessors and query methods. + # * :finder_sql - Overwrite the default generated SQL statement used to fetch the association with a manual statement + # * :delete_sql - Overwrite the default generated SQL statement used to remove links between the associated + # classes with a manual statement. + # * :insert_sql - Overwrite the default generated SQL statement used to add links between the associated classes + # with a manual statement. + # * :extend - Anonymous module for extending the proxy, see "Association extensions". + # * :include - Specify second-order associations that should be eager loaded when the collection is loaded. + # * :group - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause. + # * :limit - An integer determining the limit on the number of rows that should be returned. + # * :offset - An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows. + # * :select - By default, this is * as in SELECT * FROM, but can be changed if, for example, you want to do a join # but not include the joined columns. - # * :readonly - if set to +true+, all the associated objects are readonly through the association. + # * :readonly - If true, all the associated objects are readonly through the association. # # Option examples: # has_and_belongs_to_many :projects -- cgit v1.2.3