|
|
|
|
@@ -76,7 +76,7 @@ module ActiveRecord
|
|
|
|
|
|
|
|
|
|
# Associations are a set of macro-like class methods for tying objects together through foreign keys. They express relationships like
|
|
|
|
|
# "Project has one Project Manager" or "Project belongs to a Portfolio". Each macro adds a number of methods to the class which are
|
|
|
|
|
# specialized according to the collection or association symbol and the options hash. It works much the same way as Ruby's own attr*
|
|
|
|
|
# specialized according to the collection or association symbol and the options hash. It works much the same way as Ruby's own <tt>attr*</tt>
|
|
|
|
|
# methods. Example:
|
|
|
|
|
#
|
|
|
|
|
# class Project < ActiveRecord::Base
|
|
|
|
|
@@ -146,12 +146,12 @@ module ActiveRecord
|
|
|
|
|
#
|
|
|
|
|
# ActiveRecord associations can be used to describe relations with one-to-one, one-to-many
|
|
|
|
|
# and many-to-many cardinality. Each model uses an association to describe its role in
|
|
|
|
|
# the relation. In each case, the belongs_to association is used in the model that has
|
|
|
|
|
# the relation. In each case, the +belongs_to+ association is used in the model that has
|
|
|
|
|
# the foreign key.
|
|
|
|
|
#
|
|
|
|
|
# === One-to-one
|
|
|
|
|
#
|
|
|
|
|
# Use has_one in the base, and belongs_to in the associated model.
|
|
|
|
|
# Use +has_one+ in the base, and +belongs_to+ in the associated model.
|
|
|
|
|
#
|
|
|
|
|
# class Employee < ActiveRecord::Base
|
|
|
|
|
# has_one :office
|
|
|
|
|
@@ -162,7 +162,7 @@ module ActiveRecord
|
|
|
|
|
#
|
|
|
|
|
# === One-to-many
|
|
|
|
|
#
|
|
|
|
|
# Use has_many in the base, and belongs_to in the associated model.
|
|
|
|
|
# Use +has_many+ in the base, and +belongs_to+ in the associated model.
|
|
|
|
|
#
|
|
|
|
|
# class Manager < ActiveRecord::Base
|
|
|
|
|
# has_many :employees
|
|
|
|
|
@@ -175,7 +175,7 @@ module ActiveRecord
|
|
|
|
|
#
|
|
|
|
|
# There are two ways to build a many-to-many relationship.
|
|
|
|
|
#
|
|
|
|
|
# The first way uses a has_many association with the :through option and a join model, so
|
|
|
|
|
# The first way uses a +has_many+ association with the <tt>:through</tt> option and a join model, so
|
|
|
|
|
# there are two stages of associations.
|
|
|
|
|
#
|
|
|
|
|
# class Assignment < ActiveRecord::Base
|
|
|
|
|
@@ -191,7 +191,7 @@ module ActiveRecord
|
|
|
|
|
# has_many :programmers, :through => :assignments
|
|
|
|
|
# end
|
|
|
|
|
#
|
|
|
|
|
# For the second way, use has_and_belongs_to_many in both models. This requires a join table
|
|
|
|
|
# For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table
|
|
|
|
|
# that has no corresponding model or primary key.
|
|
|
|
|
#
|
|
|
|
|
# class Programmer < ActiveRecord::Base
|
|
|
|
|
@@ -201,15 +201,15 @@ module ActiveRecord
|
|
|
|
|
# has_and_belongs_to_many :programmers # foreign keys in the join table
|
|
|
|
|
# end
|
|
|
|
|
#
|
|
|
|
|
# It is not always a simple decision which way of building a many-to-many relationship is best.
|
|
|
|
|
# But if you need to work with the relationship model as its own entity, then you'll need to
|
|
|
|
|
# use has_many :through. Use has_and_belongs_to_many when working with legacy schemas or when
|
|
|
|
|
# Choosing which way to build a many-to-many relationship is not always simple.
|
|
|
|
|
# If you need to work with the relationship model as its own entity,
|
|
|
|
|
# use <tt>has_many :through</tt>. Use +has_and_belongs_to_many+ when working with legacy schemas or when
|
|
|
|
|
# you never work directly with the relationship itself.
|
|
|
|
|
#
|
|
|
|
|
# == Is it a belongs_to or has_one association?
|
|
|
|
|
# == Is it a +belongs_to+ or +has_one+ association?
|
|
|
|
|
#
|
|
|
|
|
# Both express a 1-1 relationship, the difference is mostly where to place the foreign key, which goes on the table for the class
|
|
|
|
|
# saying belongs_to. Example:
|
|
|
|
|
# Both express a 1-1 relationship. The difference is mostly where to place the foreign key, which goes on the table for the class
|
|
|
|
|
# declaring the +belongs_to+ relationship. Example:
|
|
|
|
|
#
|
|
|
|
|
# class User < ActiveRecord::Base
|
|
|
|
|
# # I reference an account.
|
|
|
|
|
@@ -243,26 +243,26 @@ module ActiveRecord
|
|
|
|
|
#
|
|
|
|
|
# === One-to-one associations
|
|
|
|
|
#
|
|
|
|
|
# * Assigning an object to a has_one association automatically saves that object and the object being replaced (if there is one), in
|
|
|
|
|
# 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
|
|
|
|
|
# * Assigning an object to a +has_one+ association automatically saves that object and the object being replaced (if there is one), in
|
|
|
|
|
# order to update their primary keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
|
|
|
|
|
# * 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).
|
|
|
|
|
# * 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.
|
|
|
|
|
# * If you wish to assign an object to a +has_one+ association without saving it, use the <tt>#association.build</tt> 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.
|
|
|
|
|
#
|
|
|
|
|
# === Collections
|
|
|
|
|
#
|
|
|
|
|
# * Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object
|
|
|
|
|
# * 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).
|
|
|
|
|
# * All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved.
|
|
|
|
|
# * If saving any of the objects being added to a collection (via <tt>#push</tt> or similar) fails, then <tt>#push</tt> returns +false+.
|
|
|
|
|
# * You can add an object to a collection without automatically saving it by using the <tt>#collection.build</tt> method (documented below).
|
|
|
|
|
# * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically saved when the parent is saved.
|
|
|
|
|
#
|
|
|
|
|
# === Association callbacks
|
|
|
|
|
#
|
|
|
|
|
# Similiar to the normal callbacks that hook into the lifecycle of an Active Record object, you can also define callbacks that get
|
|
|
|
|
# trigged when you add an object to or removing an object from a association collection. Example:
|
|
|
|
|
# trigged when you add an object to or remove an object from an association collection. Example:
|
|
|
|
|
#
|
|
|
|
|
# class Project
|
|
|
|
|
# has_and_belongs_to_many :developers, :after_add => :evaluate_velocity
|
|
|
|
|
@@ -278,14 +278,14 @@ module ActiveRecord
|
|
|
|
|
# has_and_belongs_to_many :developers, :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
|
|
|
|
|
# end
|
|
|
|
|
#
|
|
|
|
|
# Possible callbacks are: before_add, after_add, before_remove and after_remove.
|
|
|
|
|
# Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
|
|
|
|
|
#
|
|
|
|
|
# Should any of the before_add callbacks throw an exception, the object does not get added to the collection. Same with
|
|
|
|
|
# the before_remove callbacks, if an exception is thrown the object doesn't get removed.
|
|
|
|
|
# Should any of the +before_add+ callbacks throw an exception, the object does not get added to the collection. Same with
|
|
|
|
|
# the +before_remove+ callbacks; if an exception is thrown the object doesn't get removed.
|
|
|
|
|
#
|
|
|
|
|
# === Association extensions
|
|
|
|
|
#
|
|
|
|
|
# The proxy objects that controls the access to associations can be extended through anonymous modules. This is especially
|
|
|
|
|
# The proxy objects that control the access to associations can be extended through anonymous modules. This is especially
|
|
|
|
|
# beneficial for adding new finders, creators, and other factory-type methods that are only used as part of this association.
|
|
|
|
|
# Example:
|
|
|
|
|
#
|
|
|
|
|
@@ -319,7 +319,7 @@ module ActiveRecord
|
|
|
|
|
# has_many :people, :extend => FindOrCreateByNameExtension
|
|
|
|
|
# end
|
|
|
|
|
#
|
|
|
|
|
# If you need to use multiple named extension modules, you can specify an array of modules with the :extend option.
|
|
|
|
|
# If you need to use multiple named extension modules, you can specify an array of modules with the <tt>:extend</tt> option.
|
|
|
|
|
# In the case of name conflicts between methods in the modules, methods in modules later in the array supercede
|
|
|
|
|
# those earlier in the array. Example:
|
|
|
|
|
#
|
|
|
|
|
@@ -332,12 +332,12 @@ module ActiveRecord
|
|
|
|
|
#
|
|
|
|
|
# * +proxy_owner+ - Returns the object the association is part of.
|
|
|
|
|
# * +proxy_reflection+ - Returns the reflection object that describes the association.
|
|
|
|
|
# * +proxy_target+ - Returns the associated object for belongs_to and has_one, or the collection of associated objects for has_many and has_and_belongs_to_many.
|
|
|
|
|
# * +proxy_target+ - Returns the associated object for +belongs_to+ and +has_one+, or the collection of associated objects for +has_many+ and +has_and_belongs_to_many+.
|
|
|
|
|
#
|
|
|
|
|
# === Association Join Models
|
|
|
|
|
#
|
|
|
|
|
# Has Many associations can be configured with the :through option to use an explicit join model to retrieve the data. This
|
|
|
|
|
# operates similarly to a <tt>has_and_belongs_to_many</tt> association. The advantage is that you're able to add validations,
|
|
|
|
|
# Has Many associations can be configured with the <tt>:through</tt> option to use an explicit join model to retrieve the data. This
|
|
|
|
|
# operates similarly to a +has_and_belongs_to_many+ association. The advantage is that you're able to add validations,
|
|
|
|
|
# callbacks, and extra attributes on the join model. Consider the following schema:
|
|
|
|
|
#
|
|
|
|
|
# class Author < ActiveRecord::Base
|
|
|
|
|
@@ -354,7 +354,7 @@ module ActiveRecord
|
|
|
|
|
# @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to.
|
|
|
|
|
# @author.books # selects all books by using the Authorship join model
|
|
|
|
|
#
|
|
|
|
|
# You can also go through a has_many association on the join model:
|
|
|
|
|
# You can also go through a +has_many+ association on the join model:
|
|
|
|
|
#
|
|
|
|
|
# class Firm < ActiveRecord::Base
|
|
|
|
|
# has_many :clients
|
|
|
|
|
@@ -377,25 +377,25 @@ module ActiveRecord
|
|
|
|
|
# === Polymorphic Associations
|
|
|
|
|
#
|
|
|
|
|
# Polymorphic associations on models are not restricted on what types of models they can be associated with. Rather, they
|
|
|
|
|
# specify an interface that a has_many association must adhere to.
|
|
|
|
|
# specify an interface that a +has_many+ association must adhere to.
|
|
|
|
|
#
|
|
|
|
|
# class Asset < ActiveRecord::Base
|
|
|
|
|
# belongs_to :attachable, :polymorphic => true
|
|
|
|
|
# end
|
|
|
|
|
#
|
|
|
|
|
# class Post < ActiveRecord::Base
|
|
|
|
|
# has_many :assets, :as => :attachable # The <tt>:as</tt> option specifies the polymorphic interface to use.
|
|
|
|
|
# has_many :assets, :as => :attachable # The :as option specifies the polymorphic interface to use.
|
|
|
|
|
# end
|
|
|
|
|
#
|
|
|
|
|
# @asset.attachable = @post
|
|
|
|
|
#
|
|
|
|
|
# This works by using a type column in addition to a foreign key to specify the associated record. In the Asset example, you'd need
|
|
|
|
|
# an attachable_id integer column and an attachable_type string column.
|
|
|
|
|
# an +attachable_id+ integer column and an +attachable_type+ string column.
|
|
|
|
|
#
|
|
|
|
|
# Using polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order
|
|
|
|
|
# for the associations to work as expected, ensure that you store the base model for the STI models in the
|
|
|
|
|
# type column of the polymorphic association. To continue with the asset example above, suppose there are guest posts
|
|
|
|
|
# and member posts that use the posts table for STI. So there will be an additional 'type' column in the posts table.
|
|
|
|
|
# and member posts that use the posts table for STI. In this case, there must be a +type+ column in the posts table.
|
|
|
|
|
#
|
|
|
|
|
# class Asset < ActiveRecord::Base
|
|
|
|
|
# belongs_to :attachable, :polymorphic => true
|
|
|
|
|
@@ -431,7 +431,7 @@ module ActiveRecord
|
|
|
|
|
# == Eager loading of associations
|
|
|
|
|
#
|
|
|
|
|
# Eager loading is a way to find objects of a certain class and a number of named associations along with it in a single SQL call. This is
|
|
|
|
|
# one of the easiest ways of to prevent the dreaded 1+N problem in which fetching 100 posts that each needs to display their author
|
|
|
|
|
# one of the easiest ways of to prevent the dreaded 1+N problem in which fetching 100 posts that each need to display their author
|
|
|
|
|
# triggers 101 database queries. Through the use of eager loading, the 101 queries can be reduced to 1. Example:
|
|
|
|
|
#
|
|
|
|
|
# class Post < ActiveRecord::Base
|
|
|
|
|
@@ -451,16 +451,16 @@ module ActiveRecord
|
|
|
|
|
#
|
|
|
|
|
# for post in Post.find(:all, :include => :author)
|
|
|
|
|
#
|
|
|
|
|
# This references the name of the belongs_to association that also used the :author symbol, so the find will now weave in a join something
|
|
|
|
|
# like this: LEFT OUTER JOIN authors ON authors.id = posts.author_id. Doing so will cut down the number of queries from 201 to 101.
|
|
|
|
|
# This references the name of the +belongs_to+ association that also used the <tt>:author</tt> symbol, so the find will now weave in a join something
|
|
|
|
|
# like this: <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Doing so will cut down the number of queries from 201 to 101.
|
|
|
|
|
#
|
|
|
|
|
# We can improve upon the situation further by referencing both associations in the finder with:
|
|
|
|
|
#
|
|
|
|
|
# for post in Post.find(:all, :include => [ :author, :comments ])
|
|
|
|
|
#
|
|
|
|
|
# That'll add another join along the lines of: LEFT OUTER JOIN comments ON comments.post_id = posts.id. And we'll be down to 1 query.
|
|
|
|
|
# That'll add another join along the lines of: <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt>. And we'll be down to 1 query.
|
|
|
|
|
#
|
|
|
|
|
# To include a deep hierarchy of associations, using a hash:
|
|
|
|
|
# To include a deep hierarchy of associations, use a hash:
|
|
|
|
|
#
|
|
|
|
|
# for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ])
|
|
|
|
|
#
|
|
|
|
|
@@ -472,12 +472,12 @@ module ActiveRecord
|
|
|
|
|
# catch-all for performance problems, but it's a great way to cut down on the number of queries in a situation as the one described above.
|
|
|
|
|
#
|
|
|
|
|
# Since the eager loading pulls from multiple tables, you'll have to disambiguate any column references in both conditions and orders. So
|
|
|
|
|
# :order => "posts.id DESC" will work while :order => "id DESC" will not. Because eager loading generates the SELECT statement too, the
|
|
|
|
|
# :select option is ignored.
|
|
|
|
|
# <tt>:order => "posts.id DESC"</tt> will work while <tt>:order => "id DESC"</tt> will not. Because eager loading generates the +SELECT+ statement too, the
|
|
|
|
|
# <tt>:select</tt> option is ignored.
|
|
|
|
|
#
|
|
|
|
|
# You can use eager loading on multiple associations from the same table, but you cannot use those associations in orders and conditions
|
|
|
|
|
# as there is currently not any way to disambiguate them. Eager loading will not pull additional attributes on join tables, so "rich
|
|
|
|
|
# associations" with has_and_belongs_to_many are not a good fit for eager loading.
|
|
|
|
|
# associations" with +has_and_belongs_to_many+ are not a good fit for eager loading.
|
|
|
|
|
#
|
|
|
|
|
# When eager loaded, conditions are interpolated in the context of the model class, not the model instance. Conditions are lazily interpolated
|
|
|
|
|
# before the actual model exists.
|
|
|
|
|
@@ -485,7 +485,7 @@ module ActiveRecord
|
|
|
|
|
# == Table Aliasing
|
|
|
|
|
#
|
|
|
|
|
# ActiveRecord uses table aliasing in the case that a table is referenced multiple times in a join. If a table is referenced only once,
|
|
|
|
|
# the standard table name is used. The second time, the table is aliased as #{reflection_name}_#{parent_table_name}. Indexes are appended
|
|
|
|
|
# the standard table name is used. The second time, the table is aliased as <tt>#{reflection_name}_#{parent_table_name}</tt>. Indexes are appended
|
|
|
|
|
# for any more successive uses of the table name.
|
|
|
|
|
#
|
|
|
|
|
# Post.find :all, :include => :comments
|
|
|
|
|
@@ -505,9 +505,9 @@ module ActiveRecord
|
|
|
|
|
# TreeMixin.find :all, :include => {:children => {:parent => :children}}
|
|
|
|
|
# # => SELECT ... FROM mixins LEFT OUTER JOIN mixins childrens_mixins ...
|
|
|
|
|
# LEFT OUTER JOIN parents_mixins ...
|
|
|
|
|
# LEFT OUTER JOIN mixins childrens_mixins_2
|
|
|
|
|
# LEFT OUTER JOIN mixins childrens_mixins_2
|
|
|
|
|
#
|
|
|
|
|
# Has and Belongs to Many join tables use the same idea, but add a _join suffix:
|
|
|
|
|
# Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix:
|
|
|
|
|
#
|
|
|
|
|
# Post.find :all, :include => :categories
|
|
|
|
|
# # => SELECT ... FROM posts LEFT OUTER JOIN categories_posts ... LEFT OUTER JOIN categories ...
|
|
|
|
|
@@ -519,7 +519,7 @@ module ActiveRecord
|
|
|
|
|
# LEFT OUTER JOIN categories_posts posts_categories_join LEFT OUTER JOIN posts posts_categories
|
|
|
|
|
# LEFT OUTER JOIN categories_posts categories_posts_join LEFT OUTER JOIN categories categories_posts
|
|
|
|
|
#
|
|
|
|
|
# If you wish to specify your own custom joins using a :joins option, those table names will take precedence over the eager associations..
|
|
|
|
|
# If you wish to specify your own custom joins using a <tt>:joins</tt> option, those table names will take precedence over the eager associations:
|
|
|
|
|
#
|
|
|
|
|
# Post.find :all, :include => :comments, :joins => "inner join comments ..."
|
|
|
|
|
# # => SELECT ... FROM posts LEFT OUTER JOIN comments_posts ON ... INNER JOIN comments ...
|
|
|
|
|
@@ -544,8 +544,8 @@ module ActiveRecord
|
|
|
|
|
# end
|
|
|
|
|
# end
|
|
|
|
|
#
|
|
|
|
|
# When Firm#clients is called, it'll in turn call <tt>MyApplication::Business::Company.find(firm.id)</tt>. If you want to associate
|
|
|
|
|
# with a class in another module scope this can be done by specifying the complete class name, such as:
|
|
|
|
|
# When <tt>Firm#clients</tt> is called, it will in turn call <tt>MyApplication::Business::Company.find(firm.id)</tt>. 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
|
|
|
|
|
# module Business
|
|
|
|
|
@@ -559,41 +559,41 @@ module ActiveRecord
|
|
|
|
|
# end
|
|
|
|
|
# end
|
|
|
|
|
#
|
|
|
|
|
# == Type safety with ActiveRecord::AssociationTypeMismatch
|
|
|
|
|
# == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt>
|
|
|
|
|
#
|
|
|
|
|
# If you attempt to assign an object to an association that doesn't match the inferred or specified <tt>:class_name</tt>, you'll
|
|
|
|
|
# get a ActiveRecord::AssociationTypeMismatch.
|
|
|
|
|
# get an <tt>ActiveRecord::AssociationTypeMismatch</tt>.
|
|
|
|
|
#
|
|
|
|
|
# == Options
|
|
|
|
|
#
|
|
|
|
|
# All of the association macros can be specialized through options which makes more complex cases than the simple and guessable ones
|
|
|
|
|
# All of the association macros can be specialized through options. This makes cases more complex than the simple and guessable ones
|
|
|
|
|
# possible.
|
|
|
|
|
module ClassMethods
|
|
|
|
|
# Adds the following methods for retrieval and query of collections of associated objects.
|
|
|
|
|
# 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
|
|
|
|
|
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
|
|
|
|
|
# * <tt>collection(force_reload = false)</tt> - returns an array of all the associated objects.
|
|
|
|
|
# An empty array is returned if none are found.
|
|
|
|
|
# * <tt>collection<<(object, ...)</tt> - adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
|
|
|
|
# * <tt>collection.delete(object, ...)</tt> - 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.
|
|
|
|
|
# This will also destroy the objects if they're declared as +belongs_to+ and dependent on this model.
|
|
|
|
|
# * <tt>collection=objects</tt> - replaces the collections content by deleting and adding objects as appropriate.
|
|
|
|
|
# * <tt>collection_singular_ids</tt> - returns an array of the associated objects ids
|
|
|
|
|
# * <tt>collection_singular_ids</tt> - returns an array of the associated objects' ids
|
|
|
|
|
# * <tt>collection_singular_ids=ids</tt> - replace the collection by the objects identified by the primary keys in +ids+
|
|
|
|
|
# * <tt>collection.clear</tt> - removes every object from the collection. This destroys the associated objects if they
|
|
|
|
|
# are associated with <tt>:dependent => :destroy</tt>, deletes them directly from the database if <tt>:dependent => :delete_all</tt>,
|
|
|
|
|
# and sets their foreign keys to NULL otherwise.
|
|
|
|
|
# * <tt>collection.empty?</tt> - returns true if there are no associated objects.
|
|
|
|
|
# or otherwise sets their foreign keys to NULL.
|
|
|
|
|
# * <tt>collection.empty?</tt> - returns +true+ if there are no associated objects.
|
|
|
|
|
# * <tt>collection.size</tt> - returns the number of associated objects.
|
|
|
|
|
# * <tt>collection.find</tt> - finds an associated object according to the same rules as Base.find.
|
|
|
|
|
# * <tt>collection.build(attributes = {}, ...)</tt> - 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!
|
|
|
|
|
# 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+!
|
|
|
|
|
# * <tt>collection.create(attributes = {})</tt> - returns a new object of the collection type that has been instantiated
|
|
|
|
|
# with +attributes+ and 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!
|
|
|
|
|
# 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 <tt>has_many :clients</tt>, which will add:
|
|
|
|
|
# Example: A +Firm+ class declares <tt>has_many :clients</tt>, which will add:
|
|
|
|
|
# * <tt>Firm#clients</tt> (similar to <tt>Clients.find :all, :conditions => "firm_id = #{id}"</tt>)
|
|
|
|
|
# * <tt>Firm#clients<<</tt>
|
|
|
|
|
# * <tt>Firm#clients.delete</tt>
|
|
|
|
|
@@ -612,47 +612,47 @@ module ActiveRecord
|
|
|
|
|
# * <tt>:class_name</tt> - specify the class name of the association. Use it only if that name can't be inferred
|
|
|
|
|
# from the association name. So <tt>has_many :products</tt> will by default be linked to the +Product+ class, but
|
|
|
|
|
# if the real class name is +SpecialProduct+, you'll have to specify it with this option.
|
|
|
|
|
# * <tt>:conditions</tt> - specify the conditions that the associated objects must meet in order to be included as a "WHERE"
|
|
|
|
|
# sql fragment, such as "price > 5 AND name LIKE 'B%'".
|
|
|
|
|
# * <tt>:order</tt> - specify the order in which the associated objects are returned as a "ORDER BY" sql fragment,
|
|
|
|
|
# such as "last_name, first_name DESC"
|
|
|
|
|
# * <tt>:group</tt> - specify the attribute by which the associated objects are returned as a "GROUP BY" sql fragment,
|
|
|
|
|
# such as "category"
|
|
|
|
|
# * <tt>:conditions</tt> - specify the conditions that the associated objects must meet in order to be included as a +WHERE+
|
|
|
|
|
# SQL fragment, such as <tt>price > 5 AND name LIKE 'B%'</tt>.
|
|
|
|
|
# * <tt>:order</tt> - specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
|
|
|
|
|
# such as <tt>last_name, first_name DESC</tt>
|
|
|
|
|
# * <tt>:group</tt> - specify the attribute by which the associated objects are returned as a <tt>GROUP BY</tt> SQL fragment,
|
|
|
|
|
# such as +category+
|
|
|
|
|
# * <tt>:foreign_key</tt> - 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.
|
|
|
|
|
# * <tt>:dependent</tt> - 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
|
|
|
|
|
# objects' foreign keys are set to NULL *without* calling their save callbacks.
|
|
|
|
|
# NOTE: :dependent => true is deprecated and has been replaced with :dependent => :destroy.
|
|
|
|
|
# May not be set if :exclusively_dependent is also set.
|
|
|
|
|
# * <tt>:exclusively_dependent</tt> - Deprecated; equivalent to :dependent => :delete_all. If set to true all
|
|
|
|
|
# the associated object are deleted in one SQL statement without having their
|
|
|
|
|
# before_destroy callback run. This should only be used on associations that depend solely on this class and don't need to do any
|
|
|
|
|
# clean-up in before_destroy. The upside is that it's much faster, especially if there's a counter_cache involved.
|
|
|
|
|
# May not be set if :dependent is also set.
|
|
|
|
|
# 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+.
|
|
|
|
|
# * <tt>:dependent</tt> - if set to <tt>:destroy</tt> all the associated objects are destroyed
|
|
|
|
|
# alongside this object by calling their destroy method. If set to <tt>:delete_all</tt> all associated
|
|
|
|
|
# objects are deleted *without* calling their destroy method. If set to <tt>:nullify</tt> all associated
|
|
|
|
|
# objects' foreign keys are set to +NULL+ *without* calling their save callbacks.
|
|
|
|
|
# NOTE: <tt>:dependent => true</tt> is deprecated and has been replaced with <tt>:dependent => :destroy</tt>.
|
|
|
|
|
# May not be set if <tt>:exclusively_dependent</tt> is also set.
|
|
|
|
|
# * <tt>:exclusively_dependent</tt> - Deprecated; equivalent to <tt>:dependent => :delete_all</tt>. If set to +true+ all
|
|
|
|
|
# the associated objects are deleted in one SQL statement without having their
|
|
|
|
|
# +before_destroy+ callback run. This should only be used on associations that depend solely on this class and don't need to do any
|
|
|
|
|
# clean-up in +before_destroy+. The upside is that it's much faster, especially if there's a +counter_cache+ involved.
|
|
|
|
|
# May not be set if <tt>:dependent</tt> is also set.
|
|
|
|
|
# * <tt>:finder_sql</tt> - specify a complete SQL statement to fetch the association. This is a good way to go for complex
|
|
|
|
|
# associations that depend on multiple tables. Note: When this option is used, +find_in_collection+ is _not_ added.
|
|
|
|
|
# * <tt>:counter_sql</tt> - specify a complete SQL statement to fetch the size of the association. If +:finder_sql+ is
|
|
|
|
|
# specified but +:counter_sql+, +:counter_sql+ will be generated by replacing SELECT ... FROM with SELECT COUNT(*) FROM.
|
|
|
|
|
# * <tt>:extend</tt> - specify a named module for extending the proxy, see "Association extensions".
|
|
|
|
|
# * <tt>:counter_sql</tt> - specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
|
|
|
|
|
# specified but <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
|
|
|
|
|
# * <tt>:extend</tt> - specify a named module for extending the proxy. See "Association extensions".
|
|
|
|
|
# * <tt>:include</tt> - specify second-order associations that should be eager loaded when the collection is loaded.
|
|
|
|
|
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
|
|
|
|
|
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</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 the first 4 rows.
|
|
|
|
|
# * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you for example want to do a join, but not
|
|
|
|
|
# include the joined columns.
|
|
|
|
|
# * <tt>:as</tt>: Specifies a polymorphic interface (See #belongs_to).
|
|
|
|
|
# * <tt>:through</tt>: Specifies a Join Model to perform the query through. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt>
|
|
|
|
|
# * <tt>:select</tt>: By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if you for example want to do a join,
|
|
|
|
|
# but not include the joined columns.
|
|
|
|
|
# * <tt>:as</tt>: Specifies a polymorphic interface (See <tt>#belongs_to</tt>).
|
|
|
|
|
# * <tt>:through</tt>: Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt>
|
|
|
|
|
# are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a <tt>belongs_to</tt>
|
|
|
|
|
# or <tt>has_many</tt> association on the join model.
|
|
|
|
|
# * <tt>:source</tt>: Specifies the source association name used by <tt>has_many :through</tt> queries. Only use it if the name cannot be
|
|
|
|
|
# inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either +:subscribers+ or
|
|
|
|
|
# +:subscriber+ on +Subscription+, unless a +:source+ is given.
|
|
|
|
|
# * <tt>:source_type</tt>: Specifies type of the source association used by <tt>has_many :through</tt> queries where the source association
|
|
|
|
|
# is a polymorphic belongs_to.
|
|
|
|
|
# * <tt>:uniq</tt> - if set to true, duplicates will be omitted from the collection. Useful in conjunction with :through.
|
|
|
|
|
# inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either <tt>:subscribers</tt> or
|
|
|
|
|
# <tt>:subscriber</tt> on +Subscription+, unless a <tt>:source</tt> is given.
|
|
|
|
|
# * <tt>:source_type</tt>: Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
|
|
|
|
|
# association is a polymorphic +belongs_to+.
|
|
|
|
|
# * <tt>:uniq</tt> - if set to +true+, duplicates will be omitted from the collection. Useful in conjunction with <tt>:through</tt>.
|
|
|
|
|
#
|
|
|
|
|
# Option examples:
|
|
|
|
|
# has_many :comments, :order => "posted_on"
|
|
|
|
|
@@ -684,18 +684,18 @@ module ActiveRecord
|
|
|
|
|
add_deprecated_api_for_has_many(reflection.name)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Adds the following methods for retrieval and query of a single associated object.
|
|
|
|
|
# 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
|
|
|
|
|
# <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
|
|
|
|
|
# * <tt>association(force_reload = false)</tt> - returns the associated object. Nil is returned if none is found.
|
|
|
|
|
# * <tt>association(force_reload = false)</tt> - returns the associated object. +nil+ is returned if none is found.
|
|
|
|
|
# * <tt>association=(associate)</tt> - assigns the associate object, extracts the primary key, sets it as the foreign key,
|
|
|
|
|
# and saves the associate object.
|
|
|
|
|
# * <tt>association.nil?</tt> - returns true if there is no associated object.
|
|
|
|
|
# * <tt>association.nil?</tt> - returns +true+ if there is no associated object.
|
|
|
|
|
# * <tt>build_association(attributes = {})</tt> - 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.
|
|
|
|
|
# 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+.
|
|
|
|
|
# * <tt>create_association(attributes = {})</tt> - returns a new object of the associated type that has been instantiated
|
|
|
|
|
# with +attributes+ and linked to this object through a foreign key and that has already been saved (if it passed the validation).
|
|
|
|
|
# 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 <tt>has_one :beneficiary</tt>, which will add:
|
|
|
|
|
# * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.find(:first, :conditions => "account_id = #{id}")</tt>)
|
|
|
|
|
@@ -710,18 +710,18 @@ module ActiveRecord
|
|
|
|
|
# * <tt>:class_name</tt> - specify the class name of the association. Use it only if that name can't be inferred
|
|
|
|
|
# from the association name. So <tt>has_one :manager</tt> 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.
|
|
|
|
|
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a "WHERE"
|
|
|
|
|
# sql fragment, such as "rank = 5".
|
|
|
|
|
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a +WHERE+
|
|
|
|
|
# SQL fragment, such as <tt>rank = 5</tt>.
|
|
|
|
|
# * <tt>:order</tt> - specify the order from which the associated object will be picked at the top. Specified as
|
|
|
|
|
# an "ORDER BY" sql fragment, such as "last_name, first_name DESC"
|
|
|
|
|
# * <tt>:dependent</tt> - if set to :destroy (or true) 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.
|
|
|
|
|
# an <tt>ORDER BY</tt> SQL fragment, such as <tt>last_name, first_name DESC</tt>
|
|
|
|
|
# * <tt>:dependent</tt> - if set to <tt>:destroy</tt> (or +true+), the associated object is destroyed when this object is. If set to
|
|
|
|
|
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to <tt>:nullify</tt>, the associated
|
|
|
|
|
# object's foreign key is set to +NULL+. Also, association is assigned.
|
|
|
|
|
# * <tt>:foreign_key</tt> - 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.
|
|
|
|
|
# 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+.
|
|
|
|
|
# * <tt>:include</tt> - specify second-order associations that should be eager loaded when this object is loaded.
|
|
|
|
|
# * <tt>:as</tt>: Specifies a polymorphic interface (See #belongs_to).
|
|
|
|
|
# * <tt>:as</tt>: Specifies a polymorphic interface (See <tt>#belongs_to</tt>).
|
|
|
|
|
#
|
|
|
|
|
# Option examples:
|
|
|
|
|
# has_one :credit_card, :dependent => :destroy # destroys the associated credit card
|
|
|
|
|
@@ -753,16 +753,16 @@ module ActiveRecord
|
|
|
|
|
deprecated_association_comparison_method(reflection.name, reflection.class_name)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Adds the following methods for retrieval and query for a single associated object that this object holds an id to.
|
|
|
|
|
# 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
|
|
|
|
|
# <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
|
|
|
|
|
# * <tt>association(force_reload = false)</tt> - returns the associated object. Nil is returned if none is found.
|
|
|
|
|
# * <tt>association(force_reload = false)</tt> - returns the associated object. +nil+ is returned if none is found.
|
|
|
|
|
# * <tt>association=(associate)</tt> - assigns the associate object, extracts the primary key, and sets it as the foreign key.
|
|
|
|
|
# * <tt>association.nil?</tt> - returns true if there is no associated object.
|
|
|
|
|
# * <tt>association.nil?</tt> - returns +true+ if there is no associated object.
|
|
|
|
|
# * <tt>build_association(attributes = {})</tt> - 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.
|
|
|
|
|
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
|
|
|
|
|
# * <tt>create_association(attributes = {})</tt> - returns a new object of the associated type that has been instantiated
|
|
|
|
|
# with +attributes+ and linked to this object through a foreign key and that has already been saved (if it passed the validation).
|
|
|
|
|
# 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 <tt>belongs_to :author</tt>, which will add:
|
|
|
|
|
# * <tt>Post#author</tt> (similar to <tt>Author.find(author_id)</tt>)
|
|
|
|
|
@@ -777,20 +777,20 @@ module ActiveRecord
|
|
|
|
|
# * <tt>:class_name</tt> - specify the class name of the association. Use it only if that name can't be inferred
|
|
|
|
|
# from the association name. So <tt>has_one :author</tt> 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.
|
|
|
|
|
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a "WHERE"
|
|
|
|
|
# sql fragment, such as "authorized = 1".
|
|
|
|
|
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a +WHERE+
|
|
|
|
|
# SQL fragment, such as <tt>authorized = 1</tt>.
|
|
|
|
|
# * <tt>:order</tt> - specify the order from which the associated object will be picked at the top. Specified as
|
|
|
|
|
# an "ORDER BY" sql fragment, such as "last_name, first_name DESC"
|
|
|
|
|
# an <tt>ORDER BY</tt> SQL fragment, such as <tt>last_name, first_name DESC</tt>
|
|
|
|
|
# * <tt>:foreign_key</tt> - specify the 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 a +Person+ class that makes a belongs_to association to a
|
|
|
|
|
# +Boss+ class will use "boss_id" as the default foreign_key.
|
|
|
|
|
# * <tt>:counter_cache</tt> - caches the number of belonging objects on the associate class through 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 given that
|
|
|
|
|
# name instead of a true/false value to this option (e.g., <tt>:counter_cache => :my_custom_counter</tt>.)
|
|
|
|
|
# of the associated class in lower-case and +_id+ suffixed. So a +Person+ class that makes a +belongs_to+ association to a
|
|
|
|
|
# +Boss+ class will use +boss_id+ as the default +foreign_key+.
|
|
|
|
|
# * <tt>:counter_cache</tt> - caches the number of belonging objects on the associate class through 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 <tt>#{table_name}_count</tt> (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., <tt>:counter_cache => :my_custom_counter</tt>.)
|
|
|
|
|
# * <tt>:include</tt> - specify second-order associations that should be eager loaded when this object is loaded.
|
|
|
|
|
# * <tt>:polymorphic</tt> - specify this association is a polymorphic association by passing true.
|
|
|
|
|
# * <tt>:polymorphic</tt> - specify this association is a polymorphic association by passing +true+.
|
|
|
|
|
#
|
|
|
|
|
# Option examples:
|
|
|
|
|
# belongs_to :firm, :foreign_key => "client_of"
|
|
|
|
|
@@ -863,8 +863,8 @@ 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
|
|
|
|
|
# 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 <tt><</tt> operator for <tt>String</tt>. 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 <tt>paper_boxes</tt> and <tt>papers</tt>
|
|
|
|
|
@@ -873,37 +873,37 @@ module ActiveRecord
|
|
|
|
|
# custom <tt>join_table</tt> 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
|
|
|
|
|
# ReadOnly (because we can't save changes to the additional attrbutes). It's strongly recommended that you upgrade any
|
|
|
|
|
# +has_and_belongs_to_many+ associations. Records returned from join tables with additional attributes will be marked as
|
|
|
|
|
# +ReadOnly+ (because we can't save changes to the additional attrbutes). It's strongly recommended that you upgrade any
|
|
|
|
|
# associations with attributes to a real join model (see introduction).
|
|
|
|
|
#
|
|
|
|
|
# Adds the following methods for retrieval and query.
|
|
|
|
|
# Adds the following methods for retrieval and query:
|
|
|
|
|
# +collection+ is replaced with the symbol passed as the first argument, so
|
|
|
|
|
# <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
|
|
|
|
|
# * <tt>collection(force_reload = false)</tt> - returns an array of all the associated objects.
|
|
|
|
|
# An empty array is returned if none is found.
|
|
|
|
|
# An empty array is returned if none are found.
|
|
|
|
|
# * <tt>collection<<(object, ...)</tt> - 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).
|
|
|
|
|
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
|
|
|
|
|
# * <tt>collection.push_with_attributes(object, join_attributes)</tt> - adds one to the collection by creating an association in the join table that
|
|
|
|
|
# also holds the attributes from <tt>join_attributes</tt> (should be a hash with the column names as keys). This can be used to have additional
|
|
|
|
|
# attributes on the join, which will be injected into the associated objects when they are retrieved through the collection.
|
|
|
|
|
# (collection.concat_with_attributes is an alias to this method). This method is now deprecated.
|
|
|
|
|
# (<tt>collection.concat_with_attributes</tt> is an alias to this method). This method is now deprecated.
|
|
|
|
|
# * <tt>collection.delete(object, ...)</tt> - removes one or more objects from the collection by removing their associations from the join table.
|
|
|
|
|
# This does not destroy the objects.
|
|
|
|
|
# * <tt>collection=objects</tt> - replaces the collections content by deleting and adding objects as appropriate.
|
|
|
|
|
# * <tt>collection_singular_ids</tt> - returns an array of the associated objects ids
|
|
|
|
|
# * <tt>collection=objects</tt> - replaces the collection's content by deleting and adding objects as appropriate.
|
|
|
|
|
# * <tt>collection_singular_ids</tt> - returns an array of the associated objects' ids
|
|
|
|
|
# * <tt>collection_singular_ids=ids</tt> - replace the collection by the objects identified by the primary keys in +ids+
|
|
|
|
|
# * <tt>collection.clear</tt> - removes every object from the collection. This does not destroy the objects.
|
|
|
|
|
# * <tt>collection.empty?</tt> - returns true if there are no associated objects.
|
|
|
|
|
# * <tt>collection.empty?</tt> - returns +true+ if there are no associated objects.
|
|
|
|
|
# * <tt>collection.size</tt> - returns the number of associated objects.
|
|
|
|
|
# * <tt>collection.find(id)</tt> - finds an associated object responding to the +id+ and that
|
|
|
|
|
# meets the condition that it has to be associated with this object.
|
|
|
|
|
# * <tt>collection.build(attributes = {})</tt> - 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.
|
|
|
|
|
# with +attributes+ and linked to this object through the join table, but has not yet been saved.
|
|
|
|
|
# * <tt>collection.create(attributes = {})</tt> - returns a new object of the collection type that has been instantiated
|
|
|
|
|
# with +attributes+ and linked to this object through the join table and that has already been saved (if it passed the validation).
|
|
|
|
|
# with +attributes+, linked to this object through the join table, and that has already been saved (if it passed the validation).
|
|
|
|
|
#
|
|
|
|
|
# Example: An Developer class declares <tt>has_and_belongs_to_many :projects</tt>, which will add:
|
|
|
|
|
# Example: A Developer class declares <tt>has_and_belongs_to_many :projects</tt>, which will add:
|
|
|
|
|
# * <tt>Developer#projects</tt>
|
|
|
|
|
# * <tt>Developer#projects<<</tt>
|
|
|
|
|
# * <tt>Developer#projects.delete</tt>
|
|
|
|
|
@@ -923,30 +923,30 @@ module ActiveRecord
|
|
|
|
|
# from the association name. So <tt>has_and_belongs_to_many :projects</tt> 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.
|
|
|
|
|
# * <tt>:join_table</tt> - 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.
|
|
|
|
|
# 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.
|
|
|
|
|
# * <tt>:foreign_key</tt> - 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.
|
|
|
|
|
# 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+.
|
|
|
|
|
# * <tt>:association_foreign_key</tt> - 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.
|
|
|
|
|
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a "WHERE"
|
|
|
|
|
# sql fragment, such as "authorized = 1".
|
|
|
|
|
# * <tt>:order</tt> - specify the order in which the associated objects are returned as a "ORDER BY" sql fragment, such as "last_name, first_name DESC"
|
|
|
|
|
# * <tt>:uniq</tt> - if set to true, duplicate associated objects will be ignored by accessors and query methods
|
|
|
|
|
# * <tt>:finder_sql</tt> - overwrite the default generated SQL used to fetch the association with a manual one
|
|
|
|
|
# * <tt>:delete_sql</tt> - overwrite the default generated SQL used to remove links between the associated
|
|
|
|
|
# classes with a manual one
|
|
|
|
|
# * <tt>:insert_sql</tt> - overwrite the default generated SQL used to add links between the associated classes
|
|
|
|
|
# with a manual one
|
|
|
|
|
# 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+.
|
|
|
|
|
# * <tt>:conditions</tt> - specify the conditions that the associated object must meet in order to be included as a +WHERE+
|
|
|
|
|
# SQL fragment, such as <tt>authorized = 1</tt>.
|
|
|
|
|
# * <tt>:order</tt> - specify the order in which the associated objects are returned as a <tt>ORDER BY</tt> SQL fragment, such as <tt>last_name, first_name DESC</tt>
|
|
|
|
|
# * <tt>:uniq</tt> - if set to +true+, duplicate associated objects will be ignored by accessors and query methods
|
|
|
|
|
# * <tt>:finder_sql</tt> - overwrite the default generated SQL statement used to fetch the association with a manual statement
|
|
|
|
|
# * <tt>:delete_sql</tt> - overwrite the default generated SQL statement used to remove links between the associated
|
|
|
|
|
# classes with a manual statement
|
|
|
|
|
# * <tt>:insert_sql</tt> - overwrite the default generated SQL statement used to add links between the associated classes
|
|
|
|
|
# with a manual statement
|
|
|
|
|
# * <tt>:extend</tt> - anonymous module for extending the proxy, see "Association extensions".
|
|
|
|
|
# * <tt>:include</tt> - specify second-order associations that should be eager loaded when the collection is loaded.
|
|
|
|
|
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
|
|
|
|
|
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</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 the first 4 rows.
|
|
|
|
|
# * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you for example want to do a join, but not
|
|
|
|
|
# include the joined columns.
|
|
|
|
|
# * <tt>:select</tt>: By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join
|
|
|
|
|
# but not include the joined columns.
|
|
|
|
|
#
|
|
|
|
|
# Option examples:
|
|
|
|
|
# has_and_belongs_to_many :projects
|
|
|
|
|
|