mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Merge remote branch 'docrails/master' into 3-0-stable
This commit is contained in:
@@ -9,11 +9,13 @@ module ActiveRecord
|
||||
end unless self.new_record?
|
||||
end
|
||||
|
||||
# Active Record implements aggregation through a macro-like class method called +composed_of+ for representing attributes
|
||||
# as value objects. It expresses relationships like "Account [is] composed of Money [among other things]" or "Person [is]
|
||||
# composed of [an] address". Each call to the macro adds a description of how the value objects are created from the
|
||||
# attributes of the entity object (when the entity is initialized either as a new object or from finding an existing object)
|
||||
# and how it can be turned back into attributes (when the entity is saved to the database). Example:
|
||||
# Active Record implements aggregation through a macro-like class method called +composed_of+
|
||||
# for representing attributes as value objects. It expresses relationships like "Account [is]
|
||||
# composed of Money [among other things]" or "Person [is] composed of [an] address". Each call
|
||||
# to the macro adds a description of how the value objects are created from the attributes of
|
||||
# the entity object (when the entity is initialized either as a new object or from finding an
|
||||
# existing object) and how it can be turned back into attributes (when the entity is saved to
|
||||
# the database).
|
||||
#
|
||||
# class Customer < ActiveRecord::Base
|
||||
# composed_of :balance, :class_name => "Money", :mapping => %w(balance amount)
|
||||
@@ -68,9 +70,10 @@ module ActiveRecord
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Now it's possible to access attributes from the database through the value objects instead. If you choose to name the
|
||||
# composition the same as the attribute's name, it will be the only way to access that attribute. That's the case with our
|
||||
# +balance+ attribute. You interact with the value objects just like you would any other attribute, though:
|
||||
# Now it's possible to access attributes from the database through the value objects instead. If
|
||||
# you choose to name the composition the same as the attribute's name, it will be the only way to
|
||||
# access that attribute. That's the case with our +balance+ attribute. You interact with the value
|
||||
# objects just like you would any other attribute, though:
|
||||
#
|
||||
# customer.balance = Money.new(20) # sets the Money value object and the attribute
|
||||
# customer.balance # => Money value object
|
||||
@@ -79,8 +82,8 @@ module ActiveRecord
|
||||
# customer.balance == Money.new(20) # => true
|
||||
# customer.balance < Money.new(5) # => false
|
||||
#
|
||||
# Value objects can also be composed of multiple attributes, such as the case of Address. The order of the mappings will
|
||||
# determine the order of the parameters. Example:
|
||||
# Value objects can also be composed of multiple attributes, such as the case of Address. The order
|
||||
# of the mappings will determine the order of the parameters.
|
||||
#
|
||||
# customer.address_street = "Hyancintvej"
|
||||
# customer.address_city = "Copenhagen"
|
||||
@@ -91,38 +94,43 @@ module ActiveRecord
|
||||
#
|
||||
# == Writing value objects
|
||||
#
|
||||
# Value objects are immutable and interchangeable objects that represent a given value, such as a Money object representing
|
||||
# $5. Two Money objects both representing $5 should be equal (through methods such as <tt>==</tt> and <tt><=></tt> from Comparable if ranking
|
||||
# makes sense). This is unlike entity objects where equality is determined by identity. An entity class such as Customer can
|
||||
# easily have two different objects that both have an address on Hyancintvej. Entity identity is determined by object or
|
||||
# relational unique identifiers (such as primary keys). Normal ActiveRecord::Base classes are entity objects.
|
||||
# Value objects are immutable and interchangeable objects that represent a given value, such as
|
||||
# a Money object representing $5. Two Money objects both representing $5 should be equal (through
|
||||
# methods such as <tt>==</tt> and <tt><=></tt> from Comparable if ranking makes sense). This is
|
||||
# unlike entity objects where equality is determined by identity. An entity class such as Customer can
|
||||
# easily have two different objects that both have an address on Hyancintvej. Entity identity is
|
||||
# determined by object or relational unique identifiers (such as primary keys). Normal
|
||||
# ActiveRecord::Base classes are entity objects.
|
||||
#
|
||||
# It's also important to treat the value objects as immutable. Don't allow the Money object to have its amount changed after
|
||||
# creation. Create a new Money object with the new value instead. This is exemplified by the Money#exchange_to method that
|
||||
# returns a new value object instead of changing its own values. Active Record won't persist value objects that have been
|
||||
# changed through means other than the writer method.
|
||||
# It's also important to treat the value objects as immutable. Don't allow the Money object to have
|
||||
# its amount changed after creation. Create a new Money object with the new value instead. This
|
||||
# is exemplified by the Money#exchange_to method that returns a new value object instead of changing
|
||||
# its own values. Active Record won't persist value objects that have been changed through means
|
||||
# other than the writer method.
|
||||
#
|
||||
# The immutable requirement is enforced by Active Record by freezing any object assigned as a value object. Attempting to
|
||||
# change it afterwards will result in a ActiveSupport::FrozenObjectError.
|
||||
# The immutable requirement is enforced by Active Record by freezing any object assigned as a value
|
||||
# object. Attempting to change it afterwards will result in a ActiveSupport::FrozenObjectError.
|
||||
#
|
||||
# Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not keeping value objects
|
||||
# immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable
|
||||
# Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not
|
||||
# keeping value objects immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable
|
||||
#
|
||||
# == Custom constructors and converters
|
||||
#
|
||||
# By default value objects are initialized by calling the <tt>new</tt> constructor of the value class passing each of the
|
||||
# mapped attributes, in the order specified by the <tt>:mapping</tt> option, as arguments. If the value class doesn't support
|
||||
# this convention then +composed_of+ allows a custom constructor to be specified.
|
||||
# By default value objects are initialized by calling the <tt>new</tt> constructor of the value
|
||||
# class passing each of the mapped attributes, in the order specified by the <tt>:mapping</tt>
|
||||
# option, as arguments. If the value class doesn't support this convention then +composed_of+ allows
|
||||
# a custom constructor to be specified.
|
||||
#
|
||||
# When a new value is assigned to the value object the default assumption is that the new value is an instance of the value
|
||||
# class. Specifying a custom converter allows the new value to be automatically converted to an instance of value class if
|
||||
# necessary.
|
||||
# When a new value is assigned to the value object the default assumption is that the new value
|
||||
# is an instance of the value class. Specifying a custom converter allows the new value to be automatically
|
||||
# converted to an instance of value class if necessary.
|
||||
#
|
||||
# For example, the NetworkResource model has +network_address+ and +cidr_range+ attributes that should be aggregated using the
|
||||
# NetAddr::CIDR value class (http://netaddr.rubyforge.org). The constructor for the value class is called +create+ and it
|
||||
# expects a CIDR address string as a parameter. New values can be assigned to the value object using either another
|
||||
# NetAddr::CIDR object, a string or an array. The <tt>:constructor</tt> and <tt>:converter</tt> options can be used to
|
||||
# meet these requirements:
|
||||
# For example, the NetworkResource model has +network_address+ and +cidr_range+ attributes that
|
||||
# should be aggregated using the NetAddr::CIDR value class (http://netaddr.rubyforge.org). The constructor
|
||||
# for the value class is called +create+ and it expects a CIDR address string as a parameter. New
|
||||
# values can be assigned to the value object using either another NetAddr::CIDR object, a string
|
||||
# or an array. The <tt>:constructor</tt> and <tt>:converter</tt> options can be used to meet
|
||||
# these requirements:
|
||||
#
|
||||
# class NetworkResource < ActiveRecord::Base
|
||||
# composed_of :cidr,
|
||||
@@ -149,9 +157,9 @@ module ActiveRecord
|
||||
#
|
||||
# == Finding records by a value object
|
||||
#
|
||||
# Once a +composed_of+ relationship is specified for a model, records can be loaded from the database by specifying an instance
|
||||
# of the value object in the conditions hash. The following example finds all customers with +balance_amount+ equal to 20 and
|
||||
# +balance_currency+ equal to "USD":
|
||||
# Once a +composed_of+ relationship is specified for a model, records can be loaded from the database
|
||||
# by specifying an instance of the value object in the conditions hash. The following example
|
||||
# finds all customers with +balance_amount+ equal to 20 and +balance_currency+ equal to "USD":
|
||||
#
|
||||
# Customer.find(:all, :conditions => {:balance => Money.new(20, "USD")})
|
||||
#
|
||||
@@ -160,23 +168,28 @@ module ActiveRecord
|
||||
# <tt>composed_of :address</tt> adds <tt>address</tt> and <tt>address=(new_address)</tt> methods.
|
||||
#
|
||||
# Options are:
|
||||
# * <tt>:class_name</tt> - Specifies the class name of the association. Use it only if that name can't be inferred
|
||||
# from the part id. So <tt>composed_of :address</tt> will by default be linked to the Address class, but
|
||||
# if the real class name is CompanyAddress, you'll have to specify it with this option.
|
||||
# * <tt>:mapping</tt> - Specifies the mapping of entity attributes to attributes of the value object. Each mapping
|
||||
# is represented as an array where the first item is the name of the entity attribute and the second item is the
|
||||
# name the attribute in the value object. The order in which mappings are defined determine the order in which
|
||||
# attributes are sent to the value class constructor.
|
||||
# * <tt>:class_name</tt> - Specifies the class name of the association. Use it only if that name
|
||||
# can't be inferred from the part id. So <tt>composed_of :address</tt> will by default be linked
|
||||
# to the Address class, but if the real class name is CompanyAddress, you'll have to specify it
|
||||
# with this option.
|
||||
# * <tt>:mapping</tt> - Specifies the mapping of entity attributes to attributes of the value
|
||||
# object. Each mapping is represented as an array where the first item is the name of the
|
||||
# entity attribute and the second item is the name the attribute in the value object. The
|
||||
# order in which mappings are defined determine the order in which attributes are sent to the
|
||||
# value class constructor.
|
||||
# * <tt>:allow_nil</tt> - Specifies that the value object will not be instantiated when all mapped
|
||||
# attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all mapped attributes.
|
||||
# attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all
|
||||
# mapped attributes.
|
||||
# This defaults to +false+.
|
||||
# * <tt>:constructor</tt> - A symbol specifying the name of the constructor method or a Proc that is called to
|
||||
# initialize the value object. The constructor is passed all of the mapped attributes, in the order that they
|
||||
# are defined in the <tt>:mapping option</tt>, as arguments and uses them to instantiate a <tt>:class_name</tt> object.
|
||||
# * <tt>:constructor</tt> - A symbol specifying the name of the constructor method or a Proc that
|
||||
# is called to initialize the value object. The constructor is passed all of the mapped attributes,
|
||||
# in the order that they are defined in the <tt>:mapping option</tt>, as arguments and uses them
|
||||
# to instantiate a <tt>:class_name</tt> object.
|
||||
# The default is <tt>:new</tt>.
|
||||
# * <tt>:converter</tt> - A symbol specifying the name of a class method of <tt>:class_name</tt> or a Proc that is
|
||||
# called when a new value is assigned to the value object. The converter is passed the single value that is used
|
||||
# in the assignment and is only called if the new value is not an instance of <tt>:class_name</tt>.
|
||||
# * <tt>:converter</tt> - A symbol specifying the name of a class method of <tt>:class_name</tt>
|
||||
# or a Proc that is called when a new value is assigned to the value object. The converter is
|
||||
# passed the single value that is used in the assignment and is only called if the new value is
|
||||
# not an instance of <tt>:class_name</tt>.
|
||||
#
|
||||
# Option examples:
|
||||
# composed_of :temperature, :mapping => %w(reading celsius)
|
||||
|
||||
@@ -9,8 +9,8 @@ module ActiveRecord
|
||||
# Implements the details of eager loading of Active Record associations.
|
||||
# Application developers should not use this module directly.
|
||||
#
|
||||
# ActiveRecord::Base is extended with this module. The source code in
|
||||
# ActiveRecord::Base references methods defined in this module.
|
||||
# <tt>ActiveRecord::Base</tt> is extended with this module. The source code in
|
||||
# <tt>ActiveRecord::Base</tt> references methods defined in this module.
|
||||
#
|
||||
# Note that 'eager loading' and 'preloading' are actually the same thing.
|
||||
# However, there are two different eager loading strategies.
|
||||
@@ -55,7 +55,7 @@ module ActiveRecord
|
||||
# == Parameters
|
||||
# +records+ is an array of ActiveRecord::Base. This array needs not be flat,
|
||||
# i.e. +records+ itself may also contain arrays of records. In any case,
|
||||
# +preload_associations+ will preload the associations all records by
|
||||
# +preload_associations+ will preload the all associations records by
|
||||
# flattening +records+.
|
||||
#
|
||||
# +associations+ specifies one or more associations that you want to
|
||||
@@ -110,8 +110,8 @@ module ActiveRecord
|
||||
def preload_one_association(records, association, preload_options={})
|
||||
class_to_reflection = {}
|
||||
# Not all records have the same class, so group then preload
|
||||
# group on the reflection itself so that if various subclass share the same association then we do not split them
|
||||
# unnecessarily
|
||||
# group on the reflection itself so that if various subclass share the same association then
|
||||
# we do not split them unnecessarily
|
||||
records.group_by { |record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, _records|
|
||||
raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection
|
||||
|
||||
@@ -149,7 +149,8 @@ module ActiveRecord
|
||||
seen_keys = {}
|
||||
associated_records.each do |associated_record|
|
||||
#this is a has_one or belongs_to: there should only be one record.
|
||||
#Unfortunately we can't (in portable way) ask the database for 'all records where foo_id in (x,y,z), but please
|
||||
#Unfortunately we can't (in portable way) ask the database for
|
||||
#'all records where foo_id in (x,y,z), but please
|
||||
# only one row per distinct foo_id' so this where we enforce that
|
||||
next if seen_keys[associated_record[key].to_s]
|
||||
seen_keys[associated_record[key].to_s] = true
|
||||
@@ -304,7 +305,8 @@ module ActiveRecord
|
||||
polymorph_type = options[:foreign_type]
|
||||
klasses_and_ids = {}
|
||||
|
||||
# Construct a mapping from klass to a list of ids to load and a mapping of those ids back to their parent_records
|
||||
# Construct a mapping from klass to a list of ids to load and a mapping of those ids back
|
||||
# to their parent_records
|
||||
records.each do |record|
|
||||
if klass = record.send(polymorph_type)
|
||||
klass_id = record.send(primary_key_name)
|
||||
|
||||
@@ -114,7 +114,7 @@ module ActiveRecord
|
||||
autoload :HasOneAssociation, 'active_record/associations/has_one_association'
|
||||
autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association'
|
||||
|
||||
# Clears out the association cache
|
||||
# Clears out the association cache.
|
||||
def clear_association_cache #:nodoc:
|
||||
self.class.reflect_on_all_associations.to_a.each do |assoc|
|
||||
instance_variable_set "@#{assoc.name}", nil
|
||||
@@ -122,7 +122,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
private
|
||||
# Gets the specified association instance if it responds to :loaded?, nil otherwise.
|
||||
# Returns the specified association instance if it responds to :loaded?, nil otherwise.
|
||||
def association_instance_get(name)
|
||||
ivar = "@#{name}"
|
||||
if instance_variable_defined?(ivar)
|
||||
@@ -136,10 +136,12 @@ module ActiveRecord
|
||||
instance_variable_set("@#{name}", association)
|
||||
end
|
||||
|
||||
# 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 <tt>attr*</tt>
|
||||
# methods. Example:
|
||||
# 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 <tt>attr*</tt>
|
||||
# methods.
|
||||
#
|
||||
# class Project < ActiveRecord::Base
|
||||
# belongs_to :portfolio
|
||||
@@ -148,7 +150,8 @@ module ActiveRecord
|
||||
# has_and_belongs_to_many :categories
|
||||
# end
|
||||
#
|
||||
# The project class now has the following methods (and more) to ease the traversal and manipulation of its relationships:
|
||||
# The project class now has the following methods (and more) to ease the traversal and
|
||||
# manipulation of its relationships:
|
||||
# * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt>
|
||||
# * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt>
|
||||
# * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt>
|
||||
@@ -159,8 +162,9 @@ module ActiveRecord
|
||||
#
|
||||
# === A word of warning
|
||||
#
|
||||
# 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.
|
||||
# Don't create associations that have the same name as instance methods of
|
||||
# <tt>ActiveRecord::Base</tt>. 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.
|
||||
#
|
||||
# == Auto-generated methods
|
||||
@@ -270,8 +274,8 @@ module ActiveRecord
|
||||
#
|
||||
# == 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
|
||||
# declaring the +belongs_to+ relationship. 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.
|
||||
#
|
||||
# class User < ActiveRecord::Base
|
||||
# # I reference an account.
|
||||
@@ -300,8 +304,9 @@ module ActiveRecord
|
||||
#
|
||||
# == Unsaved objects and associations
|
||||
#
|
||||
# You can manipulate objects and associations before they are saved to the database, but there is some special behavior you should be
|
||||
# aware of, mostly involving the saving of associated objects.
|
||||
# You can manipulate objects and associations before they are saved to the database, but
|
||||
# there is some special behavior you should be aware of, mostly involving the saving of
|
||||
# associated objects.
|
||||
#
|
||||
# You can set the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
|
||||
# <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association. Setting it
|
||||
@@ -310,26 +315,33 @@ 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 (<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 <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.
|
||||
# * 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 <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
|
||||
# (the owner of the collection) is not yet stored in the database.
|
||||
# * 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.
|
||||
# * 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 <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
|
||||
#
|
||||
# Similar to the normal callbacks that hook into the lifecycle of an Active Record object, you can also define callbacks that get
|
||||
# triggered when you add an object to or remove an object from an association collection. Example:
|
||||
# Similar to the normal callbacks that hook into the lifecycle of an Active Record object,
|
||||
# you can also define callbacks that get triggered when you add an object to or remove an
|
||||
# object from an association collection.
|
||||
#
|
||||
# class Project
|
||||
# has_and_belongs_to_many :developers, :after_add => :evaluate_velocity
|
||||
@@ -342,19 +354,21 @@ module ActiveRecord
|
||||
# It's possible to stack callbacks by passing them as an array. Example:
|
||||
#
|
||||
# class Project
|
||||
# has_and_belongs_to_many :developers, :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
|
||||
# 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+.
|
||||
#
|
||||
# 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 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:
|
||||
# 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.
|
||||
#
|
||||
# class Account < ActiveRecord::Base
|
||||
# has_many :people do
|
||||
@@ -369,7 +383,8 @@ module ActiveRecord
|
||||
# person.first_name # => "David"
|
||||
# person.last_name # => "Heinemeier Hansson"
|
||||
#
|
||||
# If you need to share the same extensions between many associations, you can use a named extension module. Example:
|
||||
# If you need to share the same extensions between many associations, you can use a named
|
||||
# extension module.
|
||||
#
|
||||
# module FindOrCreateByNameExtension
|
||||
# def find_or_create_by_name(name)
|
||||
@@ -386,9 +401,10 @@ 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 <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:
|
||||
# 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.
|
||||
#
|
||||
# class Account < ActiveRecord::Base
|
||||
# has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
|
||||
@@ -399,12 +415,14 @@ 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 <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,
|
||||
# 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
|
||||
@@ -418,7 +436,7 @@ module ActiveRecord
|
||||
# end
|
||||
#
|
||||
# @author = Author.find :first
|
||||
# @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to.
|
||||
# @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:
|
||||
@@ -439,7 +457,7 @@ module ActiveRecord
|
||||
#
|
||||
# @firm = Firm.find :first
|
||||
# @firm.clients.collect { |c| c.invoices }.flatten # select all invoices for all clients of the firm
|
||||
# @firm.invoices # selects all invoices by going through the Client join model.
|
||||
# @firm.invoices # selects all invoices by going through the Client join model
|
||||
#
|
||||
# Similarly you can go through a +has_one+ association on the join model:
|
||||
#
|
||||
@@ -461,16 +479,18 @@ module ActiveRecord
|
||||
# @group.users.collect { |u| u.avatar }.flatten # select all avatars for all users in the group
|
||||
# @group.avatars # selects all avatars by going through the User join model.
|
||||
#
|
||||
# An important caveat with going through +has_one+ or +has_many+ associations on the join model is that these associations are
|
||||
# *read-only*. For example, the following would not work following the previous example:
|
||||
# An important caveat with going through +has_one+ or +has_many+ associations on the
|
||||
# join model is that these associations are *read-only*. For example, the following
|
||||
# would not work following the previous example:
|
||||
#
|
||||
# @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around.
|
||||
# @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around
|
||||
# @group.avatars.delete(@group.avatars.last) # so would this
|
||||
#
|
||||
# === 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.
|
||||
# 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.
|
||||
#
|
||||
# class Asset < ActiveRecord::Base
|
||||
# belongs_to :attachable, :polymorphic => true
|
||||
@@ -482,13 +502,16 @@ module ActiveRecord
|
||||
#
|
||||
# @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.
|
||||
# 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.
|
||||
#
|
||||
# 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. In this case, there must be a +type+ column in the posts table.
|
||||
# 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. In this case, there must be a +type+
|
||||
# column in the posts table.
|
||||
#
|
||||
# class Asset < ActiveRecord::Base
|
||||
# belongs_to :attachable, :polymorphic => true
|
||||
@@ -511,9 +534,10 @@ module ActiveRecord
|
||||
#
|
||||
# == Caching
|
||||
#
|
||||
# All of the methods are built on a simple caching principle that will keep the result of the last query around unless specifically
|
||||
# instructed not to. The cache is even shared across methods to make it even cheaper to use the macro-added methods without
|
||||
# worrying too much about performance at the first go. Example:
|
||||
# All of the methods are built on a simple caching principle that will keep the result
|
||||
# of the last query around unless specifically instructed not to. The cache is even
|
||||
# shared across methods to make it even cheaper to use the macro-added methods without
|
||||
# worrying too much about performance at the first go.
|
||||
#
|
||||
# project.milestones # fetches milestones from the database
|
||||
# project.milestones.size # uses the milestone cache
|
||||
@@ -523,9 +547,10 @@ module ActiveRecord
|
||||
#
|
||||
# == Eager loading of associations
|
||||
#
|
||||
# Eager loading is a way to find objects of a certain class and a number of named associations. This is
|
||||
# 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 2. Example:
|
||||
# Eager loading is a way to find objects of a certain class and a number of named associations.
|
||||
# This is 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 2.
|
||||
#
|
||||
# class Post < ActiveRecord::Base
|
||||
# belongs_to :author
|
||||
@@ -540,44 +565,55 @@ module ActiveRecord
|
||||
# puts "Last comment on: " + post.comments.first.created_on
|
||||
# end
|
||||
#
|
||||
# To iterate over these one hundred posts, we'll generate 201 database queries. Let's first just optimize it for retrieving the author:
|
||||
# To iterate over these one hundred posts, we'll generate 201 database queries. Let's
|
||||
# first just optimize it for retrieving the author:
|
||||
#
|
||||
# for post in Post.find(:all, :include => :author)
|
||||
#
|
||||
# This references the name of the +belongs_to+ association that also used the <tt>:author</tt> symbol. After loading the posts, find
|
||||
# will collect the +author_id+ from each one and load all the referenced authors with one query. Doing so will cut down the number of queries from 201 to 102.
|
||||
# This references the name of the +belongs_to+ association that also used the <tt>:author</tt>
|
||||
# symbol. After loading the posts, find will collect the +author_id+ from each one and load
|
||||
# all the referenced authors with one query. Doing so will cut down the number of queries
|
||||
# from 201 to 102.
|
||||
#
|
||||
# We can improve upon the situation further by referencing both associations in the finder with:
|
||||
#
|
||||
# for post in Post.find(:all, :include => [ :author, :comments ])
|
||||
#
|
||||
# This will load all comments with a single query. This reduces the total number of queries to 3. More generally the number of queries
|
||||
# will be 1 plus the number of associations named (except if some of the associations are polymorphic +belongs_to+ - see below).
|
||||
# This will load all comments with a single query. This reduces the total number of queries
|
||||
# to 3. More generally the number of queries will be 1 plus the number of associations
|
||||
# named (except if some of the associations are polymorphic +belongs_to+ - see below).
|
||||
#
|
||||
# To include a deep hierarchy of associations, use a hash:
|
||||
#
|
||||
# for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ])
|
||||
#
|
||||
# That'll grab not only all the comments but all their authors and gravatar pictures. You can mix and match
|
||||
# symbols, arrays and hashes in any combination to describe the associations you want to load.
|
||||
# That'll grab not only all the comments but all their authors and gravatar pictures.
|
||||
# You can mix and match symbols, arrays and hashes in any combination to describe the
|
||||
# associations you want to load.
|
||||
#
|
||||
# All of this power shouldn't fool you into thinking that you can pull out huge amounts of data with no performance penalty just because you've reduced
|
||||
# the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it's no
|
||||
# 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.
|
||||
# All of this power shouldn't fool you into thinking that you can pull out huge amounts
|
||||
# of data with no performance penalty just because you've reduced the number of queries.
|
||||
# The database still needs to send all the data to Active Record and it still needs to
|
||||
# be processed. So it's no 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 only one table is loaded at a time, conditions or orders cannot reference tables other than the main one. If this is the case
|
||||
# Active Record falls back to the previously used LEFT OUTER JOIN based strategy. For example
|
||||
# Since only one table is loaded at a time, conditions or orders cannot reference tables
|
||||
# other than the main one. If this is the case Active Record falls back to the previously
|
||||
# used LEFT OUTER JOIN based strategy. For example
|
||||
#
|
||||
# Post.find(:all, :include => [ :author, :comments ], :conditions => ['comments.approved = ?', true])
|
||||
#
|
||||
# This will result in a single SQL query with joins along the lines of: <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and
|
||||
# <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Note that using conditions like this can have unintended consequences.
|
||||
# In the above example posts with no approved comments are not returned at all, because the conditions apply to the SQL statement as a whole
|
||||
# and not just to the association. You must disambiguate column references for this fallback to happen, for example
|
||||
# This will result in a single SQL query with joins along the lines of:
|
||||
# <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and
|
||||
# <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Note that using conditions
|
||||
# like this can have unintended consequences.
|
||||
# In the above example posts with no approved comments are not returned at all, because
|
||||
# the conditions apply to the SQL statement as a whole and not just to the association.
|
||||
# You must disambiguate column references for this fallback to happen, for example
|
||||
# <tt>:order => "author.name DESC"</tt> will work but <tt>:order => "name DESC"</tt> will not.
|
||||
#
|
||||
# If you do want eager load only some members of an association it is usually more natural to <tt>:include</tt> an association
|
||||
# which has conditions defined on it:
|
||||
# If you do want eager load only some members of an association it is usually more natural
|
||||
# to <tt>:include</tt> an association which has conditions defined on it:
|
||||
#
|
||||
# class Post < ActiveRecord::Base
|
||||
# has_many :approved_comments, :class_name => 'Comment', :conditions => ['approved = ?', true]
|
||||
@@ -585,9 +621,11 @@ module ActiveRecord
|
||||
#
|
||||
# Post.find(:all, :include => :approved_comments)
|
||||
#
|
||||
# This will load posts and eager load the +approved_comments+ association, which contains only those comments that have been approved.
|
||||
# This will load posts and eager load the +approved_comments+ association, which contains
|
||||
# only those comments that have been approved.
|
||||
#
|
||||
# If you eager load an association with a specified <tt>:limit</tt> option, it will be ignored, returning all the associated objects:
|
||||
# If you eager load an association with a specified <tt>:limit</tt> option, it will be ignored,
|
||||
# returning all the associated objects:
|
||||
#
|
||||
# class Picture < ActiveRecord::Base
|
||||
# has_many :most_recent_comments, :class_name => 'Comment', :order => 'id DESC', :limit => 10
|
||||
@@ -595,8 +633,8 @@ module ActiveRecord
|
||||
#
|
||||
# Picture.find(:first, :include => :most_recent_comments).most_recent_comments # => returns all associated comments.
|
||||
#
|
||||
# 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.
|
||||
# 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.
|
||||
#
|
||||
# Eager loading is supported with polymorphic associations.
|
||||
#
|
||||
@@ -608,17 +646,21 @@ module ActiveRecord
|
||||
#
|
||||
# Address.find(:all, :include => :addressable)
|
||||
#
|
||||
# This will execute one query to load the addresses and load the addressables with one query per addressable type.
|
||||
# For example if all the addressables are either of class Person or Company then a total of 3 queries will be executed. The list of
|
||||
# addressable types to load is determined on the back of the addresses loaded. This is not supported if Active Record has to fallback
|
||||
# to the previous implementation of eager loading and 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 query.
|
||||
# This will execute one query to load the addresses and load the addressables with one
|
||||
# query per addressable type.
|
||||
# For example if all the addressables are either of class Person or Company then a total
|
||||
# of 3 queries will be executed. The list of addressable types to load is determined on
|
||||
# the back of the addresses loaded. This is not supported if Active Record has to fallback
|
||||
# to the previous implementation of eager loading and 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 query.
|
||||
#
|
||||
# == Table Aliasing
|
||||
#
|
||||
# Active Record 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 <tt>#{reflection_name}_#{parent_table_name}</tt>. Indexes are appended
|
||||
# for any more successive uses of the table name.
|
||||
# Active Record 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 <tt>#{reflection_name}_#{parent_table_name}</tt>.
|
||||
# Indexes are appended for any more successive uses of the table name.
|
||||
#
|
||||
# Post.find :all, :joins => :comments
|
||||
# # => SELECT ... FROM posts INNER JOIN comments ON ...
|
||||
@@ -651,7 +693,8 @@ module ActiveRecord
|
||||
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
|
||||
# INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
|
||||
#
|
||||
# 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:
|
||||
# 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, :joins => :comments, :joins => "inner join comments ..."
|
||||
# # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
|
||||
@@ -660,7 +703,8 @@ module ActiveRecord
|
||||
# INNER JOIN comments special_comments_posts ...
|
||||
# INNER JOIN comments ...
|
||||
#
|
||||
# Table aliases are automatically truncated according to the maximum length of table identifiers according to the specific database.
|
||||
# Table aliases are automatically truncated according to the maximum length of table identifiers
|
||||
# according to the specific database.
|
||||
#
|
||||
# == Modules
|
||||
#
|
||||
@@ -676,9 +720,10 @@ module ActiveRecord
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# When <tt>Firm#clients</tt> is called, it will in turn call <tt>MyApplication::Business::Client.find_all_by_firm_id(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:
|
||||
# When <tt>Firm#clients</tt> is called, it will in turn call
|
||||
# <tt>MyApplication::Business::Client.find_all_by_firm_id(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.
|
||||
#
|
||||
# module MyApplication
|
||||
# module Business
|
||||
@@ -694,8 +739,8 @@ module ActiveRecord
|
||||
#
|
||||
# == Bi-directional associations
|
||||
#
|
||||
# When you specify an association there is usually an association on the associated model that specifies the same
|
||||
# relationship in reverse. For example, with the following models:
|
||||
# When you specify an association there is usually an association on the associated model
|
||||
# that specifies the same relationship in reverse. For example, with the following models:
|
||||
#
|
||||
# class Dungeon < ActiveRecord::Base
|
||||
# has_many :traps
|
||||
@@ -710,9 +755,11 @@ module ActiveRecord
|
||||
# belongs_to :dungeon
|
||||
# end
|
||||
#
|
||||
# The +traps+ association on +Dungeon+ and the the +dungeon+ association on +Trap+ are the inverse of each other and the
|
||||
# inverse of the +dungeon+ association on +EvilWizard+ is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
|
||||
# Active Record doesn't know anything about these inverse relationships and so no object loading optimisation is possible. For example:
|
||||
# The +traps+ association on +Dungeon+ and the the +dungeon+ association on +Trap+ are
|
||||
# the inverse of each other and the inverse of the +dungeon+ association on +EvilWizard+
|
||||
# is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
|
||||
# Active Record doesn't know anything about these inverse relationships and so no object
|
||||
# loading optimisation is possible. For example:
|
||||
#
|
||||
# d = Dungeon.first
|
||||
# t = d.traps.first
|
||||
@@ -720,9 +767,11 @@ module ActiveRecord
|
||||
# d.level = 10
|
||||
# d.level == t.dungeon.level # => false
|
||||
#
|
||||
# The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to the same object data from the database, but are
|
||||
# actually different in-memory copies of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell
|
||||
# Active Record about inverse relationships and it will optimise object loading. For example, if we changed our model definitions to:
|
||||
# The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to
|
||||
# the same object data from the database, but are actually different in-memory copies
|
||||
# of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell
|
||||
# Active Record about inverse relationships and it will optimise object loading. For
|
||||
# example, if we changed our model definitions to:
|
||||
#
|
||||
# class Dungeon < ActiveRecord::Base
|
||||
# has_many :traps, :inverse_of => :dungeon
|
||||
@@ -737,8 +786,8 @@ module ActiveRecord
|
||||
# belongs_to :dungeon, :inverse_of => :evil_wizard
|
||||
# end
|
||||
#
|
||||
# Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same in-memory instance and our final <tt>d.level == t.dungeon.level</tt>
|
||||
# will return +true+.
|
||||
# Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
|
||||
# in-memory instance and our final <tt>d.level == t.dungeon.level</tt> will return +true+.
|
||||
#
|
||||
# There are limitations to <tt>:inverse_of</tt> support:
|
||||
#
|
||||
@@ -748,13 +797,13 @@ module ActiveRecord
|
||||
#
|
||||
# == 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 an <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 an <tt>ActiveRecord::AssociationTypeMismatch</tt>.
|
||||
#
|
||||
# == Options
|
||||
#
|
||||
# All of the association macros can be specialized through options. This makes cases more complex than the simple and guessable ones
|
||||
# possible.
|
||||
# All of the association macros can be specialized through options. This makes cases
|
||||
# more complex than the simple and guessable ones possible.
|
||||
module ClassMethods
|
||||
# Specifies a one-to-many association. The following methods for retrieval and query of
|
||||
# collections of associated objects will be added:
|
||||
@@ -828,20 +877,22 @@ module ActiveRecord
|
||||
# === Supported options
|
||||
# [:class_name]
|
||||
# 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.
|
||||
# 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.
|
||||
# [:conditions]
|
||||
# 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>. Record creations from the association are scoped if a hash
|
||||
# is used. <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt>
|
||||
# or <tt>@blog.posts.build</tt>.
|
||||
# SQL fragment, such as <tt>price > 5 AND name LIKE 'B%'</tt>. Record creations from
|
||||
# the association are scoped if a hash is used.
|
||||
# <tt>has_many :posts, :conditions => {:published => true}</tt> will create published
|
||||
# posts with <tt>@blog.posts.create</tt> or <tt>@blog.posts.build</tt>.
|
||||
# [:order]
|
||||
# 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>.
|
||||
# [: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 <tt>:foreign_key</tt>.
|
||||
# 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 <tt>:foreign_key</tt>.
|
||||
# [:primary_key]
|
||||
# Specify the method that returns the primary key used for the association. By default this is +id+.
|
||||
# [:dependent]
|
||||
@@ -855,10 +906,12 @@ module ActiveRecord
|
||||
#
|
||||
# [:finder_sql]
|
||||
# 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.
|
||||
# associations that depend on multiple tables. Note: When this option is used, +find_in_collection+
|
||||
# is _not_ added.
|
||||
# [:counter_sql]
|
||||
# Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
|
||||
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
|
||||
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by
|
||||
# replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
|
||||
# [:extend]
|
||||
# Specify a named module for extending the proxy. See "Association extensions".
|
||||
# [:include]
|
||||
@@ -866,25 +919,31 @@ module ActiveRecord
|
||||
# [:group]
|
||||
# An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
|
||||
# [:having]
|
||||
# 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.
|
||||
# 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.
|
||||
# [: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.
|
||||
# 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 <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. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||
# 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. Do not forget
|
||||
# to include the primary and foreign keys, otherwise it will raise an error.
|
||||
# [:as]
|
||||
# Specifies a polymorphic interface (See <tt>belongs_to</tt>).
|
||||
# [:through]
|
||||
# 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>
|
||||
# <tt>has_one</tt> or <tt>has_many</tt> association on the join model. The collection of join models can be managed via the collection
|
||||
# API. For example, new join models are created for newly associated objects, and if some are gone their rows are deleted (directly,
|
||||
# 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>, <tt>has_one</tt>
|
||||
# or <tt>has_many</tt> association on the join model. The collection of join models
|
||||
# can be managed via the collection API. For example, new join models are created for
|
||||
# newly associated objects, and if some are gone their rows are deleted (directly,
|
||||
# no destroy callbacks are triggered).
|
||||
# [:source]
|
||||
# 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 <tt>:subscribers</tt> or
|
||||
# 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 <tt>:subscribers</tt> or
|
||||
# <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
|
||||
# [:source_type]
|
||||
# Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
|
||||
@@ -896,12 +955,14 @@ module ActiveRecord
|
||||
# [:validate]
|
||||
# If false, don't validate the associated objects when saving the parent object. true by default.
|
||||
# [:autosave]
|
||||
# If true, always save the associated objects or destroy them if marked for destruction, when saving the parent object.
|
||||
# If true, always save the associated objects or destroy them if marked for destruction,
|
||||
# when saving the parent object.
|
||||
# If false, never save or destroy the associated objects.
|
||||
# By default, only save associated objects that are new records.
|
||||
# [:inverse_of]
|
||||
# Specifies the name of the <tt>belongs_to</tt> association on the associated object that is the inverse of this <tt>has_many</tt>
|
||||
# association. Does not work in combination with <tt>:through</tt> or <tt>:as</tt> options.
|
||||
# Specifies the name of the <tt>belongs_to</tt> association on the associated object
|
||||
# that is the inverse of this <tt>has_many</tt> association. Does not work in combination
|
||||
# with <tt>:through</tt> or <tt>:as</tt> options.
|
||||
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
||||
#
|
||||
# Option examples:
|
||||
@@ -975,19 +1036,20 @@ module ActiveRecord
|
||||
# [:conditions]
|
||||
# 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>. Record creation from the association is scoped if a hash
|
||||
# is used. <tt>has_one :account, :conditions => {:enabled => true}</tt> will create an enabled account with <tt>@company.create_account</tt>
|
||||
# or <tt>@company.build_account</tt>.
|
||||
# is used. <tt>has_one :account, :conditions => {:enabled => true}</tt> will create
|
||||
# an enabled account with <tt>@company.create_account</tt> or <tt>@company.build_account</tt>.
|
||||
# [:order]
|
||||
# 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>.
|
||||
# [:dependent]
|
||||
# If set to <tt>:destroy</tt>, 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>: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.
|
||||
# [: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 <tt>:foreign_key</tt>.
|
||||
# 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 <tt>:foreign_key</tt>.
|
||||
# [:primary_key]
|
||||
# Specify the method that returns the primary key used for the association. By default this is +id+.
|
||||
# [:include]
|
||||
@@ -995,15 +1057,18 @@ module ActiveRecord
|
||||
# [:as]
|
||||
# Specifies a polymorphic interface (See <tt>belongs_to</tt>).
|
||||
# [:select]
|
||||
# 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. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||
# 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. Do not forget to include the
|
||||
# primary and foreign keys, otherwise it will raise an error.
|
||||
# [:through]
|
||||
# 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>has_one</tt> or <tt>belongs_to</tt> association on the join model.
|
||||
# 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>has_one</tt> or <tt>belongs_to</tt>
|
||||
# association on the join model.
|
||||
# [:source]
|
||||
# Specifies the source association name used by <tt>has_one :through</tt> queries. Only use it if the name cannot be
|
||||
# inferred from the association. <tt>has_one :favorite, :through => :favorites</tt> will look for a
|
||||
# Specifies the source association name used by <tt>has_one :through</tt> queries.
|
||||
# Only use it if the name cannot be inferred from the association.
|
||||
# <tt>has_one :favorite, :through => :favorites</tt> will look for a
|
||||
# <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
|
||||
# [:source_type]
|
||||
# Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
|
||||
@@ -1013,17 +1078,19 @@ module ActiveRecord
|
||||
# [:validate]
|
||||
# If false, don't validate the associated object when saving the parent object. +false+ by default.
|
||||
# [:autosave]
|
||||
# If true, always save the associated object or destroy it if marked for destruction, when saving the parent object.
|
||||
# If false, never save or destroy the associated object.
|
||||
# If true, always save the associated object or destroy it if marked for destruction,
|
||||
# when saving the parent object. If false, never save or destroy the associated object.
|
||||
# By default, only save the associated object if it's a new record.
|
||||
# [:inverse_of]
|
||||
# Specifies the name of the <tt>belongs_to</tt> association on the associated object that is the inverse of this <tt>has_one</tt>
|
||||
# association. Does not work in combination with <tt>:through</tt> or <tt>:as</tt> options.
|
||||
# Specifies the name of the <tt>belongs_to</tt> association on the associated object
|
||||
# that is the inverse of this <tt>has_one</tt> association. Does not work in combination
|
||||
# with <tt>:through</tt> or <tt>:as</tt> options.
|
||||
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
||||
#
|
||||
# Option examples:
|
||||
# has_one :credit_card, :dependent => :destroy # destroys the associated credit card
|
||||
# has_one :credit_card, :dependent => :nullify # updates the associated records foreign key value to NULL rather than destroying it
|
||||
# has_one :credit_card, :dependent => :nullify # updates the associated records foreign
|
||||
# # key value to NULL rather than destroying it
|
||||
# has_one :last_comment, :class_name => "Comment", :order => "posted_on"
|
||||
# has_one :project_manager, :class_name => "Person", :conditions => "role = 'project_manager'"
|
||||
# has_one :attachment, :as => :attachable
|
||||
@@ -1085,27 +1152,34 @@ module ActiveRecord
|
||||
# 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>.
|
||||
# [:select]
|
||||
# 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. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||
# 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. Do not
|
||||
# forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||
# [: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 <tt>belongs_to :person</tt> association will use
|
||||
# "person_id" as the default <tt>:foreign_key</tt>. Similarly, <tt>belongs_to :favorite_person, :class_name => "Person"</tt>
|
||||
# will use a foreign key of "favorite_person_id".
|
||||
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
|
||||
# association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
|
||||
# <tt>belongs_to :favorite_person, :class_name => "Person"</tt> will use a foreign key
|
||||
# of "favorite_person_id".
|
||||
# [:primary_key]
|
||||
# Specify the method that returns the primary key of associated object used for the association. By default this is id.
|
||||
# Specify the method that returns the primary key of associated object used for the association.
|
||||
# By default this is id.
|
||||
# [:dependent]
|
||||
# If set to <tt>:destroy</tt>, 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. This option should not be specified when
|
||||
# <tt>belongs_to</tt> is used in conjunction with a <tt>has_many</tt> relationship on another class because of the potential to leave
|
||||
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
|
||||
# This option should not be specified when <tt>belongs_to</tt> is used in conjunction with
|
||||
# a <tt>has_many</tt> 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+
|
||||
# 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>.)
|
||||
# Note: Specifying a counter cache will add it to that model's list of readonly attributes using +attr_readonly+.
|
||||
# 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>.)
|
||||
# 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.
|
||||
# [:polymorphic]
|
||||
@@ -1117,15 +1191,18 @@ module ActiveRecord
|
||||
# [:validate]
|
||||
# If false, don't validate the associated objects when saving the parent object. +false+ by default.
|
||||
# [:autosave]
|
||||
# If true, always save the associated object or destroy it if marked for destruction, when saving the parent object.
|
||||
# If true, always save the associated object or destroy it if marked for destruction, when
|
||||
# saving the parent object.
|
||||
# If false, never save or destroy the associated object.
|
||||
# By default, only save the associated object if it's a new record.
|
||||
# [:touch]
|
||||
# If true, the associated object will be touched (the updated_at/on attributes set to now) when this record is either saved or
|
||||
# destroyed. If you specify a symbol, that attribute will be updated with the current time instead of the updated_at/on attribute.
|
||||
# If true, the associated object will be touched (the updated_at/on attributes set to now)
|
||||
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
||||
# will be updated with the current time instead of the updated_at/on attribute.
|
||||
# [:inverse_of]
|
||||
# Specifies the name of the <tt>has_one</tt> or <tt>has_many</tt> association on the associated object that is the inverse of this <tt>belongs_to</tt>
|
||||
# association. Does not work in combination with the <tt>:polymorphic</tt> options.
|
||||
# Specifies the name of the <tt>has_one</tt> or <tt>has_many</tt> association on the associated
|
||||
# object that is the inverse of this <tt>belongs_to</tt> association. Does not work in
|
||||
# combination with the <tt>:polymorphic</tt> options.
|
||||
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
||||
#
|
||||
# Option examples:
|
||||
@@ -1159,9 +1236,10 @@ module ActiveRecord
|
||||
# Specifies a many-to-many relationship with another class. This 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 <tt><</tt> 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
|
||||
# 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 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
|
||||
@@ -1183,9 +1261,10 @@ module ActiveRecord
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# 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 attributes). It's strongly recommended that you upgrade any
|
||||
# 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 attributes). 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:
|
||||
@@ -1225,7 +1304,8 @@ module ActiveRecord
|
||||
# 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
|
||||
# with +attributes+, 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).
|
||||
#
|
||||
# (+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>.)
|
||||
@@ -1260,8 +1340,9 @@ module ActiveRecord
|
||||
# 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
|
||||
# to Project will use "person_id" as the default <tt>:foreign_key</tt>.
|
||||
# of this class in lower-case and "_id" suffixed. So a Person class that makes
|
||||
# a +has_and_belongs_to_many+ association to Project will use "person_id" as the
|
||||
# default <tt>:foreign_key</tt>.
|
||||
# [:association_foreign_key]
|
||||
# Specify the foreign key used for the association on the receiving side of the association.
|
||||
# By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
|
||||
@@ -1269,7 +1350,8 @@ module ActiveRecord
|
||||
# the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
|
||||
# [:conditions]
|
||||
# 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>. Record creations from the association are scoped if a hash is used.
|
||||
# SQL fragment, such as <tt>authorized = 1</tt>. Record creations from the association are
|
||||
# scoped if a hash is used.
|
||||
# <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt>
|
||||
# or <tt>@blog.posts.build</tt>.
|
||||
# [:order]
|
||||
@@ -1281,7 +1363,8 @@ module ActiveRecord
|
||||
# Overwrite the default generated SQL statement used to fetch the association with a manual statement
|
||||
# [:counter_sql]
|
||||
# Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
|
||||
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
|
||||
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by
|
||||
# replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
|
||||
# [:delete_sql]
|
||||
# Overwrite the default generated SQL statement used to remove links between the associated
|
||||
# classes with a manual statement.
|
||||
@@ -1295,20 +1378,24 @@ module ActiveRecord
|
||||
# [:group]
|
||||
# An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
|
||||
# [:having]
|
||||
# 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.
|
||||
# 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.
|
||||
# [: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.
|
||||
# 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 <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. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
|
||||
# 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. Do not forget to include the primary
|
||||
# and foreign keys, otherwise it will raise an error.
|
||||
# [:readonly]
|
||||
# If true, all the associated objects are readonly through the association.
|
||||
# [:validate]
|
||||
# If false, don't validate the associated objects when saving the parent object. +true+ by default.
|
||||
# [:autosave]
|
||||
# If true, always save the associated objects or destroy them if marked for destruction, when saving the parent object.
|
||||
# If true, always save the associated objects or destroy them if marked for destruction, when
|
||||
# saving the parent object.
|
||||
# If false, never save or destroy the associated objects.
|
||||
# By default, only save associated objects that are new records.
|
||||
#
|
||||
|
||||
@@ -106,9 +106,10 @@ module ActiveRecord
|
||||
:limit => @reflection.options[:limit] } }
|
||||
end
|
||||
|
||||
# Join tables with additional columns on top of the two foreign keys must be considered ambiguous unless a select
|
||||
# clause has been explicitly defined. Otherwise you can get broken records back, if, for example, the join column also has
|
||||
# an id column. This will then overwrite the id column of the records coming back.
|
||||
# Join tables with additional columns on top of the two foreign keys must be considered
|
||||
# ambiguous unless a select clause has been explicitly defined. Otherwise you can get
|
||||
# broken records back, if, for example, the join column also has an id column. This will
|
||||
# then overwrite the id column of the records coming back.
|
||||
def finding_with_ambiguous_select?(select_clause)
|
||||
!select_clause && columns.size != 2
|
||||
end
|
||||
|
||||
@@ -24,9 +24,10 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been loaded and
|
||||
# calling collection.size if it has. If it's more likely than not that the collection does have a size larger than zero,
|
||||
# and you need to fetch that collection afterwards, it'll take one fewer SELECT query if you use #length.
|
||||
# Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been
|
||||
# loaded and calling collection.size if it has. If it's more likely than not that the collection does
|
||||
# have a size larger than zero, and you need to fetch that collection afterwards, it'll take one fewer
|
||||
# SELECT query if you use #length.
|
||||
def size
|
||||
return @owner.send(:read_attribute, cached_counter_attribute_name) if has_cached_counter?
|
||||
return @target.size if loaded?
|
||||
|
||||
@@ -14,7 +14,8 @@ module ActiveRecord
|
||||
module ClassMethods
|
||||
protected
|
||||
# Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
|
||||
# This enhanced read method automatically converts the UTC time stored in the database to the time zone stored in Time.zone.
|
||||
# This enhanced read method automatically converts the UTC time stored in the database to the time
|
||||
# zone stored in Time.zone.
|
||||
def define_method_attribute(attr_name)
|
||||
if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
|
||||
method_body, line = <<-EOV, __LINE__ + 1
|
||||
|
||||
@@ -14,8 +14,8 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+. Empty strings for fixnum and float
|
||||
# columns are turned into +nil+.
|
||||
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+. Empty strings
|
||||
# for fixnum and float columns are turned into +nil+.
|
||||
def write_attribute(attr_name, value)
|
||||
attr_name = attr_name.to_s
|
||||
attr_name = self.class.primary_key if attr_name == 'id'
|
||||
|
||||
@@ -4,14 +4,13 @@ module ActiveRecord
|
||||
# = Active Record Autosave Association
|
||||
#
|
||||
# AutosaveAssociation is a module that takes care of automatically saving
|
||||
# your associations when the parent is saved. In addition to saving, it
|
||||
# also destroys any associations that were marked for destruction.
|
||||
# associacted records when parent is saved. In addition to saving, it
|
||||
# also destroys any associated records that were marked for destruction.
|
||||
# (See mark_for_destruction and marked_for_destruction?)
|
||||
#
|
||||
# Saving of the parent, its associations, and the destruction of marked
|
||||
# associations, all happen inside 1 transaction. This should never leave the
|
||||
# database in an inconsistent state after, for instance, mass assigning
|
||||
# attributes and saving them.
|
||||
# database in an inconsistent state.
|
||||
#
|
||||
# If validations for any of the associations fail, their error messages will
|
||||
# be applied to the parent.
|
||||
@@ -21,8 +20,6 @@ module ActiveRecord
|
||||
#
|
||||
# === One-to-one Example
|
||||
#
|
||||
# Consider a Post model with one Author:
|
||||
#
|
||||
# class Post
|
||||
# has_one :author, :autosave => true
|
||||
# end
|
||||
@@ -155,11 +152,12 @@ module ActiveRecord
|
||||
CODE
|
||||
end
|
||||
|
||||
# Adds a validate and save callback for the association as specified by
|
||||
# Adds validation and save callbacks for the association as specified by
|
||||
# the +reflection+.
|
||||
#
|
||||
# For performance reasons, we don't check whether to validate at runtime,
|
||||
# but instead only define the method and callback when needed. However,
|
||||
# For performance reasons, we don't check whether to validate at runtime.
|
||||
# However the validation and callback methods are lazy and those methods
|
||||
# get created when they are invoked for the very first time. However,
|
||||
# this can change, for instance, when using nested attributes, which is
|
||||
# called _after_ the association has been defined. Since we don't want
|
||||
# the callbacks to get defined multiple times, there are guards that
|
||||
@@ -197,14 +195,15 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Reloads the attributes of the object as usual and removes a mark for destruction.
|
||||
# Reloads the attributes of the object as usual and clears <tt>marked_for_destruction</tt> flag.
|
||||
def reload(options = nil)
|
||||
@marked_for_destruction = false
|
||||
super
|
||||
end
|
||||
|
||||
# Marks this record to be destroyed as part of the parents save transaction.
|
||||
# This does _not_ actually destroy the record yet, rather it will be destroyed when <tt>parent.save</tt> is called.
|
||||
# This does _not_ actually destroy the record instantly, rather child record will be destroyed
|
||||
# when <tt>parent.save</tt> is called.
|
||||
#
|
||||
# Only useful if the <tt>:autosave</tt> option on the parent is enabled for this associated model.
|
||||
def mark_for_destruction
|
||||
@@ -249,7 +248,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
# Validate the association if <tt>:validate</tt> or <tt>:autosave</tt> is
|
||||
# turned on for the association specified by +reflection+.
|
||||
# turned on for the association.
|
||||
def validate_single_association(reflection)
|
||||
if (association = association_instance_get(reflection.name)) && !association.target.nil?
|
||||
association_valid?(reflection, association)
|
||||
@@ -357,14 +356,9 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Saves the associated record if it's new or <tt>:autosave</tt> is enabled
|
||||
# on the association.
|
||||
# Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
|
||||
#
|
||||
# In addition, it will destroy the association if it was marked for
|
||||
# destruction with mark_for_destruction.
|
||||
#
|
||||
# This all happens inside a transaction, _if_ the Transactions module is included into
|
||||
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
|
||||
# In addition, it will destroy the association if it was marked for destruction.
|
||||
def save_belongs_to_association(reflection)
|
||||
if (association = association_instance_get(reflection.name)) && !association.destroyed?
|
||||
autosave = reflection.options[:autosave]
|
||||
@@ -384,4 +378,4 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,17 +26,19 @@ require 'active_record/log_subscriber'
|
||||
module ActiveRecord #:nodoc:
|
||||
# = Active Record
|
||||
#
|
||||
# Active Record objects don't specify their attributes directly, but rather infer them from the table definition with
|
||||
# which they're linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change
|
||||
# is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain
|
||||
# Active Record objects don't specify their attributes directly, but rather infer them from
|
||||
# the table definition with which they're linked. Adding, removing, and changing attributes
|
||||
# and their type is done directly in the database. Any change is instantly reflected in the
|
||||
# Active Record objects. The mapping that binds a given Active Record class to a certain
|
||||
# database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
|
||||
#
|
||||
# See the mapping rules in table_name and the full example in link:files/README.html for more insight.
|
||||
#
|
||||
# == Creation
|
||||
#
|
||||
# Active Records accept constructor parameters either in a hash or as a block. The hash method is especially useful when
|
||||
# you're receiving the data from somewhere else, like an HTTP request. It works like this:
|
||||
# Active Records accept constructor parameters either in a hash or as a block. The hash
|
||||
# method is especially useful when you're receiving the data from somewhere else, like an
|
||||
# HTTP request. It works like this:
|
||||
#
|
||||
# user = User.new(:name => "David", :occupation => "Code Artist")
|
||||
# user.name # => "David"
|
||||
@@ -75,14 +77,17 @@ module ActiveRecord #:nodoc:
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query and is thus susceptible to SQL-injection
|
||||
# attacks if the <tt>user_name</tt> and +password+ parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
|
||||
# <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+ before inserting them in the query,
|
||||
# which will ensure that an attacker can't escape the query and fake the login (or worse).
|
||||
# The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query
|
||||
# and is thus susceptible to SQL-injection attacks if the <tt>user_name</tt> and +password+
|
||||
# parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
|
||||
# <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+
|
||||
# before inserting them in the query, which will ensure that an attacker can't escape the
|
||||
# query and fake the login (or worse).
|
||||
#
|
||||
# When using multiple parameters in the conditions, it can easily become hard to read exactly what the fourth or fifth
|
||||
# question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That's done by replacing
|
||||
# the question marks with symbols and supplying a hash with values for the matching symbol keys:
|
||||
# When using multiple parameters in the conditions, it can easily become hard to read exactly
|
||||
# what the fourth or fifth question mark is supposed to represent. In those cases, you can
|
||||
# resort to named bind variables instead. That's done by replacing the question marks with
|
||||
# symbols and supplying a hash with values for the matching symbol keys:
|
||||
#
|
||||
# Company.where(
|
||||
# "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
|
||||
@@ -103,18 +108,19 @@ module ActiveRecord #:nodoc:
|
||||
#
|
||||
# Student.where(:grade => [9,11,12])
|
||||
#
|
||||
# When joining tables, nested hashes or keys written in the form 'table_name.column_name' can be used to qualify the table name of a
|
||||
# particular condition. For instance:
|
||||
# When joining tables, nested hashes or keys written in the form 'table_name.column_name'
|
||||
# can be used to qualify the table name of a particular condition. For instance:
|
||||
#
|
||||
# Student.joins(:schools).where(:schools => { :type => 'public' })
|
||||
# Student.joins(:schools).where('schools.type' => 'public' )
|
||||
#
|
||||
# == Overwriting default accessors
|
||||
#
|
||||
# All column values are automatically available through basic accessors on the Active Record object, but sometimes you
|
||||
# want to specialize this behavior. This can be done by overwriting the default accessors (using the same
|
||||
# name as the attribute) and calling <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually change things.
|
||||
# Example:
|
||||
# All column values are automatically available through basic accessors on the Active Record
|
||||
# object, but sometimes you want to specialize this behavior. This can be done by overwriting
|
||||
# the default accessors (using the same name as the attribute) and calling
|
||||
# <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually
|
||||
# change things.
|
||||
#
|
||||
# class Song < ActiveRecord::Base
|
||||
# # Uses an integer of seconds to hold the length of the song
|
||||
@@ -128,8 +134,8 @@ module ActiveRecord #:nodoc:
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt> instead of <tt>write_attribute(:attribute, value)</tt> and
|
||||
# <tt>read_attribute(:attribute)</tt> as a shorter form.
|
||||
# You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt>
|
||||
# instead of <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>.
|
||||
#
|
||||
# == Attribute query methods
|
||||
#
|
||||
@@ -147,34 +153,43 @@ module ActiveRecord #:nodoc:
|
||||
#
|
||||
# == Accessing attributes before they have been typecasted
|
||||
#
|
||||
# Sometimes you want to be able to read the raw attribute data without having the column-determined typecast run its course first.
|
||||
# That can be done by using the <tt><attribute>_before_type_cast</tt> accessors that all attributes have. For example, if your Account model
|
||||
# has a <tt>balance</tt> attribute, you can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.
|
||||
# Sometimes you want to be able to read the raw attribute data without having the column-determined
|
||||
# typecast run its course first. That can be done by using the <tt><attribute>_before_type_cast</tt>
|
||||
# accessors that all attributes have. For example, if your Account model has a <tt>balance</tt> attribute,
|
||||
# you can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.
|
||||
#
|
||||
# This is especially useful in validation situations where the user might supply a string for an integer field and you want to display
|
||||
# the original string back in an error message. Accessing the attribute normally would typecast the string to 0, which isn't what you
|
||||
# want.
|
||||
# This is especially useful in validation situations where the user might supply a string for an
|
||||
# integer field and you want to display the original string back in an error message. Accessing the
|
||||
# attribute normally would typecast the string to 0, which isn't what you want.
|
||||
#
|
||||
# == Dynamic attribute-based finders
|
||||
#
|
||||
# Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL. They work by
|
||||
# appending the name of an attribute to <tt>find_by_</tt>, <tt>find_last_by_</tt>, or <tt>find_all_by_</tt>, so you get finders like <tt>Person.find_by_user_name</tt>,
|
||||
# <tt>Person.find_all_by_last_name</tt>, and <tt>Payment.find_by_transaction_id</tt>. So instead of writing
|
||||
# Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects
|
||||
# by simple queries without turning to SQL. They work by appending the name of an attribute
|
||||
# to <tt>find_by_</tt>, <tt>find_last_by_</tt>, or <tt>find_all_by_</tt> and thus produces finders
|
||||
# like <tt>Person.find_by_user_name</tt>, <tt>Person.find_all_by_last_name</tt>, and
|
||||
# <tt>Payment.find_by_transaction_id</tt>. Instead of writing
|
||||
# <tt>Person.where(:user_name => user_name).first</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
|
||||
# And instead of writing <tt>Person.where(:last_name => last_name).all</tt>, you just do <tt>Person.find_all_by_last_name(last_name)</tt>.
|
||||
# And instead of writing <tt>Person.where(:last_name => last_name).all</tt>, you just do
|
||||
# <tt>Person.find_all_by_last_name(last_name)</tt>.
|
||||
#
|
||||
# It's also possible to use multiple attributes in the same find by separating them with "_and_", so you get finders like
|
||||
# <tt>Person.find_by_user_name_and_password</tt> or even <tt>Payment.find_by_purchaser_and_state_and_country</tt>. So instead of writing
|
||||
# <tt>Person.where(:user_name => user_name, :password => password).first</tt>, you just do
|
||||
# <tt>Person.find_by_user_name_and_password(user_name, password)</tt>.
|
||||
# It's also possible to use multiple attributes in the same find by separating them with "_and_".
|
||||
#
|
||||
# Person.where(:user_name => user_name, :password => password).first
|
||||
# Person.find_by_user_name_and_password #with dynamic finder
|
||||
#
|
||||
# Person.where(:user_name => user_name, :password => password, :gender => 'male').first
|
||||
# Payment.find_by_user_name_and_password_and_gender
|
||||
#
|
||||
# It's even possible to call these dynamic finder methods on relations and named scopes. For example :
|
||||
# It's even possible to call these dynamic finder methods on relations and named scopes.
|
||||
#
|
||||
# Payment.order("created_on").find_all_by_amount(50)
|
||||
# Payment.pending.find_last_by_amount(100)
|
||||
#
|
||||
# The same dynamic finder style can be used to create the object if it doesn't already exist. This dynamic finder is called with
|
||||
# <tt>find_or_create_by_</tt> and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won't be set unless they are given in a block. For example:
|
||||
# The same dynamic finder style can be used to create the object if it doesn't already exist.
|
||||
# This dynamic finder is called with <tt>find_or_create_by_</tt> and will return the object if
|
||||
# it already exists and otherwise creates it, then returns it. Protected attributes won't be set
|
||||
# unless they are given in a block.
|
||||
#
|
||||
# # No 'Summer' tag exists
|
||||
# Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")
|
||||
@@ -185,23 +200,33 @@ module ActiveRecord #:nodoc:
|
||||
# # Now 'Bob' exist and is an 'admin'
|
||||
# User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }
|
||||
#
|
||||
# Use the <tt>find_or_initialize_by_</tt> finder if you want to return a new record without saving it first. Protected attributes won't be set unless they are given in a block. For example:
|
||||
# Use the <tt>find_or_initialize_by_</tt> finder if you want to return a new record without
|
||||
# saving it first. Protected attributes won't be set unless they are given in a block.
|
||||
#
|
||||
# # No 'Winter' tag exists
|
||||
# winter = Tag.find_or_initialize_by_name("Winter")
|
||||
# winter.new_record? # true
|
||||
#
|
||||
# To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of
|
||||
# a list of parameters. For example:
|
||||
# a list of parameters.
|
||||
#
|
||||
# Tag.find_or_create_by_name(:name => "rails", :creator => current_user)
|
||||
#
|
||||
# That will either find an existing tag named "rails", or create a new one while setting the user that created it.
|
||||
# That will either find an existing tag named "rails", or create a new one while setting the
|
||||
# user that created it.
|
||||
#
|
||||
# Just like <tt>find_by_*</tt>, you can also use <tt>scoped_by_*</tt> to retrieve data. The good thing about
|
||||
# using this feature is that the very first time result is returned using <tt>method_missing</tt> technique
|
||||
# but after that the method is declared on the class. Henceforth <tt>method_missing</tt> will not be hit.
|
||||
#
|
||||
# User.scoped_by_user_name('David')
|
||||
#
|
||||
# == Saving arrays, hashes, and other non-mappable objects in text columns
|
||||
#
|
||||
# Active Record can serialize any object in text columns using YAML. To do so, you must specify this with a call to the class method +serialize+.
|
||||
# This makes it possible to store arrays, hashes, and other non-mappable objects without doing any additional work. Example:
|
||||
# Active Record can serialize any object in text columns using YAML. To do so, you must
|
||||
# specify this with a call to the class method +serialize+.
|
||||
# This makes it possible to store arrays, hashes, and other non-mappable objects without doing
|
||||
# any additional work.
|
||||
#
|
||||
# class User < ActiveRecord::Base
|
||||
# serialize :preferences
|
||||
@@ -210,8 +235,8 @@ module ActiveRecord #:nodoc:
|
||||
# user = User.create(:preferences => { "background" => "black", "display" => large })
|
||||
# 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
|
||||
# descendant of a class not in the hierarchy. Example:
|
||||
# You can also specify a class option as the second parameter that'll raise an exception
|
||||
# if a serialized object is retrieved as a descendant of a class not in the hierarchy.
|
||||
#
|
||||
# class User < ActiveRecord::Base
|
||||
# serialize :preferences, Hash
|
||||
@@ -222,52 +247,63 @@ module ActiveRecord #:nodoc:
|
||||
#
|
||||
# == Single table inheritance
|
||||
#
|
||||
# Active Record allows inheritance by storing the name of the class in a column that by default is named "type" (can be changed
|
||||
# by overwriting <tt>Base.inheritance_column</tt>). This means that an inheritance looking like this:
|
||||
# Active Record allows inheritance by storing the name of the class in a column that by
|
||||
# default is named "type" (can be changed by overwriting <tt>Base.inheritance_column</tt>).
|
||||
# This means that an inheritance looking like this:
|
||||
#
|
||||
# class Company < ActiveRecord::Base; end
|
||||
# class Firm < Company; end
|
||||
# class Client < Company; end
|
||||
# class PriorityClient < Client; end
|
||||
#
|
||||
# When you do <tt>Firm.create(:name => "37signals")</tt>, this record will be saved in the companies table with type = "Firm". You can then
|
||||
# fetch this row again using <tt>Company.where(:name => '37signals').first</tt> and it will return a Firm object.
|
||||
# When you do <tt>Firm.create(:name => "37signals")</tt>, this record will be saved in
|
||||
# the companies table with type = "Firm". You can then fetch this row again using
|
||||
# <tt>Company.where(:name => '37signals').first</tt> and it will return a Firm object.
|
||||
#
|
||||
# If you don't have a type column defined in your table, single-table inheritance won't be triggered. In that case, it'll work just
|
||||
# like normal subclasses with no special magic for differentiating between them or reloading the right type with find.
|
||||
# If you don't have a type column defined in your table, single-table inheritance won't
|
||||
# be triggered. In that case, it'll work just like normal subclasses with no special magic
|
||||
# for differentiating between them or reloading the right type with find.
|
||||
#
|
||||
# Note, all the attributes for all the cases are kept in the same table. Read more:
|
||||
# http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
|
||||
#
|
||||
# == Connection to multiple databases in different models
|
||||
#
|
||||
# Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection.
|
||||
# All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection.
|
||||
# For example, if Course is an ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
|
||||
# Connections are usually created through ActiveRecord::Base.establish_connection and retrieved
|
||||
# by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this
|
||||
# connection. But you can also set a class-specific connection. For example, if Course is an
|
||||
# ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
|
||||
# and Course and all of its subclasses will use this connection instead.
|
||||
#
|
||||
# This feature is implemented by keeping a connection pool in ActiveRecord::Base that is a Hash indexed by the class. If a connection is
|
||||
# requested, the retrieve_connection method will go up the class-hierarchy until a connection is found in the connection pool.
|
||||
# This feature is implemented by keeping a connection pool in ActiveRecord::Base that is
|
||||
# a Hash indexed by the class. If a connection is requested, the retrieve_connection method
|
||||
# will go up the class-hierarchy until a connection is found in the connection pool.
|
||||
#
|
||||
# == Exceptions
|
||||
#
|
||||
# * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
|
||||
# * AdapterNotSpecified - The configuration hash used in <tt>establish_connection</tt> didn't include an
|
||||
# <tt>:adapter</tt> key.
|
||||
# * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a non-existent adapter
|
||||
# * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a
|
||||
# non-existent adapter
|
||||
# (or a bad spelling of an existing one).
|
||||
# * AssociationTypeMismatch - The object assigned to the association wasn't of the type specified in the association definition.
|
||||
# * AssociationTypeMismatch - The object assigned to the association wasn't of the type
|
||||
# specified in the association definition.
|
||||
# * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
|
||||
# * ConnectionNotEstablished+ - No connection has been established. Use <tt>establish_connection</tt> before querying.
|
||||
# * ConnectionNotEstablished+ - No connection has been established. Use <tt>establish_connection</tt>
|
||||
# before querying.
|
||||
# * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist
|
||||
# or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal
|
||||
# nothing was found, please check its documentation for further details.
|
||||
# * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
|
||||
# * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
|
||||
# <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of AttributeAssignmentError
|
||||
# <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of
|
||||
# AttributeAssignmentError
|
||||
# objects that should be inspected to determine which attributes triggered the errors.
|
||||
# * AttributeAssignmentError - An error occurred while doing a mass assignment through the <tt>attributes=</tt> method.
|
||||
# You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error.
|
||||
# * AttributeAssignmentError - An error occurred while doing a mass assignment through the
|
||||
# <tt>attributes=</tt> method.
|
||||
# You can inspect the +attribute+ property of the exception object to determine which attribute
|
||||
# triggered the error.
|
||||
#
|
||||
# *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
|
||||
# So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
|
||||
@@ -275,8 +311,9 @@ module ActiveRecord #:nodoc:
|
||||
class Base
|
||||
##
|
||||
# :singleton-method:
|
||||
# Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then passed
|
||||
# on to any new database connections made and which can be retrieved on both a class and instance level by calling +logger+.
|
||||
# Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class,
|
||||
# which is then passed on to any new database connections made and which can be retrieved on both
|
||||
# a class and instance level by calling +logger+.
|
||||
cattr_accessor :logger, :instance_writer => false
|
||||
|
||||
class << self
|
||||
@@ -323,21 +360,24 @@ module ActiveRecord #:nodoc:
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
# Accessor for the prefix type that will be prepended to every primary key column name. The options are :table_name and
|
||||
# :table_name_with_underscore. If the first is specified, the Product class will look for "productid" instead of "id" as
|
||||
# the primary column. If the latter is specified, the Product class will look for "product_id" instead of "id". Remember
|
||||
# Accessor for the prefix type that will be prepended to every primary key column name.
|
||||
# The options are :table_name and :table_name_with_underscore. If the first is specified,
|
||||
# the Product class will look for "productid" instead of "id" as the primary column. If the
|
||||
# latter is specified, the Product class will look for "product_id" instead of "id". Remember
|
||||
# that this is a global setting for all Active Records.
|
||||
cattr_accessor :primary_key_prefix_type, :instance_writer => false
|
||||
@@primary_key_prefix_type = nil
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
# Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all
|
||||
# table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace
|
||||
# for tables in a shared database. By default, the prefix is the empty string.
|
||||
# Accessor for the name of the prefix string to prepend to every table name. So if set
|
||||
# to "basecamp_", all table names will be named like "basecamp_projects", "basecamp_people",
|
||||
# etc. This is a convenient way of creating a namespace for tables in a shared database.
|
||||
# By default, the prefix is the empty string.
|
||||
#
|
||||
# If you are organising your models within modules you can add a prefix to the models within a namespace by defining
|
||||
# a singleton method in the parent module called table_name_prefix which returns your chosen prefix.
|
||||
# If you are organising your models within modules you can add a prefix to the models within
|
||||
# a namespace by defining a singleton method in the parent module called table_name_prefix which
|
||||
# returns your chosen prefix.
|
||||
class_attribute :table_name_prefix, :instance_writer => false
|
||||
self.table_name_prefix = ""
|
||||
|
||||
@@ -358,8 +398,8 @@ module ActiveRecord #:nodoc:
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
# Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates and times from the database.
|
||||
# This is set to :local by default.
|
||||
# Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling
|
||||
# dates and times from the database. This is set to :local by default.
|
||||
cattr_accessor :default_timezone, :instance_writer => false
|
||||
@@default_timezone = :local
|
||||
|
||||
@@ -505,15 +545,18 @@ module ActiveRecord #:nodoc:
|
||||
serialized_attributes[attr_name.to_s] = class_name
|
||||
end
|
||||
|
||||
# Returns a hash of all the attributes that have been specified for serialization as keys and their class restriction as values.
|
||||
# Returns a hash of all the attributes that have been specified for serialization as
|
||||
# keys and their class restriction as values.
|
||||
def serialized_attributes
|
||||
read_inheritable_attribute(:attr_serialized) or write_inheritable_attribute(:attr_serialized, {})
|
||||
end
|
||||
|
||||
# Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending
|
||||
# directly from ActiveRecord::Base. So if the hierarchy looks like: Reply < Message < ActiveRecord::Base, then Message is used
|
||||
# to guess the table name even when called on Reply. The rules used to do the guess are handled by the Inflector class
|
||||
# in Active Support, which knows almost all common English inflections. You can add new inflections in config/initializers/inflections.rb.
|
||||
# Guesses the table name (in forced lower-case) based on the name of the class in the
|
||||
# inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy
|
||||
# looks like: Reply < Message < ActiveRecord::Base, then Message is used
|
||||
# to guess the table name even when called on Reply. The rules used to do the guess
|
||||
# are handled by the Inflector class in Active Support, which knows almost all common
|
||||
# English inflections. You can add new inflections in config/initializers/inflections.rb.
|
||||
#
|
||||
# Nested classes are given table names prefixed by the singular form of
|
||||
# the parent's table name. Enclosing modules are not considered.
|
||||
@@ -923,15 +966,15 @@ module ActiveRecord #:nodoc:
|
||||
end
|
||||
end
|
||||
|
||||
# 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>where(:user_name => user_name).first</tt> and <tt>where(:user_name => user_name, :password => :password).first</tt>
|
||||
# respectively. Also works for <tt>all</tt> by using <tt>find_all_by_amount(50)</tt> that is turned into <tt>where(:amount => 50).all</tt>.
|
||||
# Enables dynamic finders like <tt>User.find_by_user_name(user_name)</tt> and
|
||||
# <tt>User.scoped_by_user_name(user_name). Refer to Dynamic attribute-based finders
|
||||
# section at the top of this file for more detailed information.
|
||||
#
|
||||
# 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>.
|
||||
# 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>.
|
||||
#
|
||||
# Each dynamic finder, scope or initializer/creator is also defined in the class after it is first invoked, so that future
|
||||
# attempts to use it do not run through method_missing.
|
||||
# Each dynamic finder using <tt>scoped_by_*</tt> is also defined in the class after it
|
||||
# is first invoked, so that future attempts to use it do not run through method_missing.
|
||||
def method_missing(method_id, *arguments, &block)
|
||||
if match = DynamicFinderMatch.match(method_id)
|
||||
attribute_names = match.attribute_names
|
||||
@@ -1607,10 +1650,11 @@ MSG
|
||||
|
||||
private
|
||||
|
||||
# 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.
|
||||
# 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.
|
||||
def ensure_proper_type
|
||||
unless self.class.descends_from_active_record?
|
||||
write_attribute(self.class.inheritance_column, self.class.sti_name)
|
||||
@@ -1659,8 +1703,9 @@ MSG
|
||||
# by calling new on the column type or aggregation type (through composed_of) object with these parameters.
|
||||
# So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
|
||||
# written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
|
||||
# parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum, f for Float,
|
||||
# s for String, and a for Array. If all the values for a given attribute are empty, the attribute will be set to nil.
|
||||
# parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum,
|
||||
# f for Float, s for String, and a for Array. If all the values for a given attribute are empty, the
|
||||
# attribute will be set to nil.
|
||||
def assign_multiparameter_attributes(pairs)
|
||||
execute_callstack_for_multiparameter_attributes(
|
||||
extract_callstack_for_multiparameter_attributes(pairs)
|
||||
|
||||
@@ -26,8 +26,8 @@ module ActiveRecord
|
||||
# <tt>after_rollback</tt>.
|
||||
#
|
||||
# That's a total of ten callbacks, which gives you immense power to react and prepare for each state in the
|
||||
# Active Record lifecycle. The sequence for calling <tt>Base#save</tt> for an existing record is similar, except that each
|
||||
# <tt>_on_create</tt> callback is replaced by the corresponding <tt>_on_update</tt> callback.
|
||||
# Active Record lifecycle. The sequence for calling <tt>Base#save</tt> for an existing record is similar,
|
||||
# except that each <tt>_on_create</tt> callback is replaced by the corresponding <tt>_on_update</tt> callback.
|
||||
#
|
||||
# Examples:
|
||||
# class CreditCard < ActiveRecord::Base
|
||||
@@ -55,9 +55,9 @@ module ActiveRecord
|
||||
#
|
||||
# == Inheritable callback queues
|
||||
#
|
||||
# Besides the overwritable callback methods, it's also possible to register callbacks through the use of the callback macros.
|
||||
# Their main advantage is that the macros add behavior into a callback queue that is kept intact down through an inheritance
|
||||
# hierarchy. Example:
|
||||
# Besides the overwritable callback methods, it's also possible to register callbacks through the
|
||||
# use of the callback macros. Their main advantage is that the macros add behavior into a callback
|
||||
# queue that is kept intact down through an inheritance hierarchy.
|
||||
#
|
||||
# class Topic < ActiveRecord::Base
|
||||
# before_destroy :destroy_author
|
||||
@@ -67,9 +67,9 @@ module ActiveRecord
|
||||
# before_destroy :destroy_readers
|
||||
# end
|
||||
#
|
||||
# Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is run, both +destroy_author+ and
|
||||
# +destroy_readers+ are called. Contrast this to the situation where we've implemented the save behavior through overwriteable
|
||||
# methods:
|
||||
# Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
|
||||
# run, both +destroy_author+ and +destroy_readers+ are called. Contrast this to the situation where
|
||||
# we've implemented the save behavior through overwriteable methods:
|
||||
#
|
||||
# class Topic < ActiveRecord::Base
|
||||
# def before_destroy() destroy_author end
|
||||
@@ -79,20 +79,21 @@ module ActiveRecord
|
||||
# def before_destroy() destroy_readers end
|
||||
# end
|
||||
#
|
||||
# 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 descendant to decide whether they want to call +super+ and trigger the inherited callbacks.
|
||||
# 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 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
|
||||
# be inherited.
|
||||
# *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 be inherited.
|
||||
#
|
||||
# == Types of callbacks
|
||||
#
|
||||
# There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
|
||||
# inline methods (using a proc), and inline eval methods (using a string). Method references and callback objects are the
|
||||
# recommended approaches, inline methods using a proc are sometimes appropriate (such as for creating mix-ins), and inline
|
||||
# eval methods are deprecated.
|
||||
# inline methods (using a proc), and inline eval methods (using a string). Method references and callback objects
|
||||
# are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for
|
||||
# creating mix-ins), and inline eval methods are deprecated.
|
||||
#
|
||||
# The method reference callbacks work by specifying a protected or private method available in the object, like this:
|
||||
#
|
||||
@@ -169,15 +170,15 @@ module ActiveRecord
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# The callback macros usually accept a symbol for the method they're supposed to run, but you can also pass a "method string",
|
||||
# which will then be evaluated within the binding of the callback. Example:
|
||||
# The callback macros usually accept a symbol for the method they're supposed to run, but you can also
|
||||
# pass a "method string", which will then be evaluated within the binding of the callback. Example:
|
||||
#
|
||||
# class Topic < ActiveRecord::Base
|
||||
# before_destroy 'self.class.delete_all "parent_id = #{id}"'
|
||||
# end
|
||||
#
|
||||
# Notice that single quotes (') are used so the <tt>#{id}</tt> part isn't evaluated until the callback is triggered. Also note that these
|
||||
# inline callbacks can be stacked just like the regular ones:
|
||||
# Notice that single quotes (') are used so the <tt>#{id}</tt> part isn't evaluated until the callback
|
||||
# is triggered. Also note that these inline callbacks can be stacked just like the regular ones:
|
||||
#
|
||||
# class Topic < ActiveRecord::Base
|
||||
# before_destroy 'self.class.delete_all "parent_id = #{id}"',
|
||||
@@ -186,22 +187,24 @@ module ActiveRecord
|
||||
#
|
||||
# == The +after_find+ and +after_initialize+ exceptions
|
||||
#
|
||||
# Because +after_find+ and +after_initialize+ are called for each object found and instantiated by a finder, such as <tt>Base.find(:all)</tt>, we've had
|
||||
# to implement a simple performance constraint (50% more speed on a simple test case). Unlike all the other callbacks, +after_find+ and
|
||||
# +after_initialize+ will only be run if an explicit implementation is defined (<tt>def after_find</tt>). In that case, all of the
|
||||
# Because +after_find+ and +after_initialize+ are called for each object found and instantiated by a finder,
|
||||
# such as <tt>Base.find(:all)</tt>, we've had to implement a simple performance constraint (50% more speed
|
||||
# on a simple test case). Unlike all the other callbacks, +after_find+ and +after_initialize+ will only be
|
||||
# run if an explicit implementation is defined (<tt>def after_find</tt>). In that case, all of the
|
||||
# callback types will be called.
|
||||
#
|
||||
# == <tt>before_validation*</tt> returning statements
|
||||
#
|
||||
# If the returning value of a +before_validation+ callback can be evaluated to +false+, the process will be aborted and <tt>Base#save</tt> will return +false+.
|
||||
# If Base#save! is called it will raise a ActiveRecord::RecordInvalid exception.
|
||||
# Nothing will be appended to the errors object.
|
||||
# If the returning value of a +before_validation+ callback can be evaluated to +false+, the process will be
|
||||
# aborted and <tt>Base#save</tt> will return +false+. If Base#save! is called it will raise a
|
||||
# ActiveRecord::RecordInvalid exception. Nothing will be appended to the errors object.
|
||||
#
|
||||
# == Canceling callbacks
|
||||
#
|
||||
# If a <tt>before_*</tt> callback returns +false+, all the later callbacks and the associated action are cancelled. If an <tt>after_*</tt> callback returns
|
||||
# +false+, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks
|
||||
# defined as methods on the model, which are called last.
|
||||
# If a <tt>before_*</tt> callback returns +false+, all the later callbacks and the associated action are
|
||||
# cancelled. If an <tt>after_*</tt> callback returns +false+, all the later callbacks are cancelled.
|
||||
# Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
|
||||
# methods on the model, which are called last.
|
||||
#
|
||||
# == Transactions
|
||||
#
|
||||
@@ -217,7 +220,8 @@ module ActiveRecord
|
||||
#
|
||||
# == Debugging callbacks
|
||||
#
|
||||
# To list the methods and procs registered with a particular callback, append <tt>_callback_chain</tt> to the callback name that you wish to list and send that to your class from the Rails console:
|
||||
# To list the methods and procs registered with a particular callback, append <tt>_callback_chain</tt> to
|
||||
# the callback name that you wish to list and send that to your class from the Rails console:
|
||||
#
|
||||
# >> Topic.after_save_callback_chain
|
||||
# => [#<ActiveSupport::Callbacks::Callback:0x3f6a448
|
||||
|
||||
@@ -23,7 +23,8 @@ module ActiveRecord
|
||||
#
|
||||
# +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
|
||||
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
|
||||
# +sql_type+ is used to extract the column's length, if necessary. For example +60+ in <tt>company_name varchar(60)</tt>.
|
||||
# +sql_type+ is used to extract the column's length, if necessary. For example +60+ in
|
||||
# <tt>company_name varchar(60)</tt>.
|
||||
# It will be mapped to one of the standard Rails SQL types in the <tt>type</tt> attribute.
|
||||
# +null+ determines if this column allows +NULL+ values.
|
||||
def initialize(name, default, sql_type = nil, null = true)
|
||||
@@ -359,7 +360,8 @@ module ActiveRecord
|
||||
#
|
||||
# Available options are (none of these exists by default):
|
||||
# * <tt>:limit</tt> -
|
||||
# Requests a maximum column length. This is number of characters for <tt>:string</tt> and <tt>:text</tt> columns and number of bytes for :binary and :integer columns.
|
||||
# Requests a maximum column length. This is number of characters for <tt>:string</tt> and
|
||||
# <tt>:text</tt> columns and number of bytes for :binary and :integer columns.
|
||||
# * <tt>:default</tt> -
|
||||
# The column's default value. Use nil for NULL.
|
||||
# * <tt>:null</tt> -
|
||||
@@ -462,8 +464,8 @@ module ActiveRecord
|
||||
# TableDefinition#timestamps that'll add created_at and +updated_at+ as datetimes.
|
||||
#
|
||||
# TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
|
||||
# column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of options, these will be
|
||||
# used when creating the <tt>_type</tt> column. So what can be written like this:
|
||||
# column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of
|
||||
# options, these will be used when creating the <tt>_type</tt> column. So what can be written like this:
|
||||
#
|
||||
# create_table :taggings do |t|
|
||||
# t.integer :tag_id, :tagger_id, :taggable_id
|
||||
|
||||
@@ -278,7 +278,8 @@ module ActiveRecord
|
||||
rows
|
||||
end
|
||||
|
||||
# Executes a SQL query and returns a MySQL::Result object. Note that you have to free the Result object after you're done using it.
|
||||
# Executes a SQL query and returns a MySQL::Result object. Note that you have to free
|
||||
# the Result object after you're done using it.
|
||||
def execute(sql, name = nil) #:nodoc:
|
||||
if name == :skip_logging
|
||||
@connection.query(sql)
|
||||
|
||||
@@ -183,10 +183,14 @@ module ActiveRecord
|
||||
# * <tt>:username</tt> - Defaults to nothing.
|
||||
# * <tt>:password</tt> - Defaults to nothing.
|
||||
# * <tt>:database</tt> - The name of the database. No default, must be provided.
|
||||
# * <tt>:schema_search_path</tt> - An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the <tt>:schema_order</tt> option.
|
||||
# * <tt>:encoding</tt> - An optional client encoding that is used in a <tt>SET client_encoding TO <encoding></tt> call on the connection.
|
||||
# * <tt>:min_messages</tt> - An optional client min messages that is used in a <tt>SET client_min_messages TO <min_messages></tt> call on the connection.
|
||||
# * <tt>:allow_concurrency</tt> - If true, use async query methods so Ruby threads don't deadlock; otherwise, use blocking query methods.
|
||||
# * <tt>:schema_search_path</tt> - An optional schema search path for the connection given
|
||||
# as a string of comma-separated schema names. This is backward-compatible with the <tt>:schema_order</tt> option.
|
||||
# * <tt>:encoding</tt> - An optional client encoding that is used in a <tt>SET client_encoding TO
|
||||
# <encoding></tt> call on the connection.
|
||||
# * <tt>:min_messages</tt> - An optional client min messages that is used in a
|
||||
# <tt>SET client_min_messages TO <min_messages></tt> call on the connection.
|
||||
# * <tt>:allow_concurrency</tt> - If true, use async query methods so Ruby threads don't deadlock;
|
||||
# otherwise, use blocking query methods.
|
||||
class PostgreSQLAdapter < AbstractAdapter
|
||||
ADAPTER_NAME = 'PostgreSQL'.freeze
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
# The SQLite adapter works with both the 2.x and 3.x series of SQLite with the sqlite-ruby drivers (available both as gems and
|
||||
# from http://rubyforge.org/projects/sqlite-ruby/).
|
||||
# The SQLite adapter works with both the 2.x and 3.x series of SQLite with the sqlite-ruby
|
||||
# drivers (available both as gems and from http://rubyforge.org/projects/sqlite-ruby/).
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
|
||||
@@ -2,8 +2,8 @@ module ActiveRecord
|
||||
|
||||
# = Active Record Dynamic Finder Match
|
||||
#
|
||||
# Provides dynamic attribute-based finders such as <tt>find_by_country</tt>
|
||||
# if, for example, the <tt>Person</tt> has an attribute with that name.
|
||||
# Refer to ActiveRecord::Base documentation for Dynamic attribute-based finders for detailed info
|
||||
#
|
||||
class DynamicFinderMatch
|
||||
def self.match(method)
|
||||
df_match = self.new(method)
|
||||
|
||||
@@ -30,7 +30,8 @@ module ActiveRecord
|
||||
class SerializationTypeMismatch < ActiveRecordError
|
||||
end
|
||||
|
||||
# Raised when adapter not specified on connection (or configuration file <tt>config/database.yml</tt> misses adapter field).
|
||||
# Raised when adapter not specified on connection (or configuration file <tt>config/database.yml</tt>
|
||||
# misses adapter field).
|
||||
class AdapterNotSpecified < ActiveRecordError
|
||||
end
|
||||
|
||||
@@ -38,7 +39,8 @@ module ActiveRecord
|
||||
class AdapterNotFound < ActiveRecordError
|
||||
end
|
||||
|
||||
# Raised when connection to the database could not been established (for example when <tt>connection=</tt> is given a nil object).
|
||||
# Raised when connection to the database could not been established (for example when <tt>connection=</tt>
|
||||
# is given a nil object).
|
||||
class ConnectionNotEstablished < ActiveRecordError
|
||||
end
|
||||
|
||||
@@ -51,7 +53,8 @@ module ActiveRecord
|
||||
class RecordNotSaved < ActiveRecordError
|
||||
end
|
||||
|
||||
# Raised when SQL statement cannot be executed by the database (for example, it's often the case for MySQL when Ruby driver used is too old).
|
||||
# Raised when SQL statement cannot be executed by the database (for example, it's often the case for
|
||||
# MySQL when Ruby driver used is too old).
|
||||
class StatementInvalid < ActiveRecordError
|
||||
end
|
||||
|
||||
@@ -78,7 +81,8 @@ module ActiveRecord
|
||||
class InvalidForeignKey < WrappedDatabaseException
|
||||
end
|
||||
|
||||
# Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
|
||||
# Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example,
|
||||
# when using +find+ method)
|
||||
# does not match number of expected variables.
|
||||
#
|
||||
# For example, in
|
||||
@@ -165,4 +169,4 @@ module ActiveRecord
|
||||
@errors = errors
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,9 +39,10 @@ end
|
||||
# This type of fixture is in YAML format and the preferred default. YAML is a file format which describes data structures
|
||||
# in a non-verbose, human-readable format. It ships with Ruby 1.8.1+.
|
||||
#
|
||||
# Unlike single-file fixtures, YAML fixtures are stored in a single file per model, which are placed in the directory appointed
|
||||
# by <tt>ActiveSupport::TestCase.fixture_path=(path)</tt> (this is automatically configured for Rails, so you can just
|
||||
# put your files in <tt><your-rails-app>/test/fixtures/</tt>). The fixture file ends with the <tt>.yml</tt> file extension (Rails example:
|
||||
# Unlike single-file fixtures, YAML fixtures are stored in a single file per model, which are placed
|
||||
# in the directory appointed by <tt>ActiveSupport::TestCase.fixture_path=(path)</tt> (this is
|
||||
# automatically configured for Rails, so you can just put your files in <tt><your-rails-app>/test/fixtures/</tt>).
|
||||
# The fixture file ends with the <tt>.yml</tt> file extension (Rails example:
|
||||
# <tt><your-rails-app>/test/fixtures/web_sites.yml</tt>). The format of a YAML fixture file looks like this:
|
||||
#
|
||||
# rubyonrails:
|
||||
@@ -58,7 +59,8 @@ end
|
||||
# indented list of key/value pairs in the "key: value" format. Records are separated by a blank line for your viewing
|
||||
# pleasure.
|
||||
#
|
||||
# Note that YAML fixtures are unordered. If you want ordered fixtures, use the omap YAML type. See http://yaml.org/type/omap.html
|
||||
# Note that YAML fixtures are unordered. If you want ordered fixtures, use the omap YAML type.
|
||||
# See http://yaml.org/type/omap.html
|
||||
# for the specification. You will need ordered fixtures when you have foreign key constraints on keys in the same table.
|
||||
# This is commonly needed for tree structures. Example:
|
||||
#
|
||||
@@ -79,7 +81,8 @@ end
|
||||
# (Rails example: <tt><your-rails-app>/test/fixtures/web_sites.csv</tt>).
|
||||
#
|
||||
# The format of this type of fixture file is much more compact than the others, but also a little harder to read by us
|
||||
# humans. The first line of the CSV file is a comma-separated list of field names. The rest of the file is then comprised
|
||||
# humans. The first line of the CSV file is a comma-separated list of field names. The rest of the
|
||||
# file is then comprised
|
||||
# of the actual data (1 per line). Here's an example:
|
||||
#
|
||||
# id, name, url
|
||||
@@ -99,15 +102,16 @@ end
|
||||
#
|
||||
# == Single-file fixtures
|
||||
#
|
||||
# This type of fixture was the original format for Active Record that has since been deprecated in favor of the YAML and CSV formats.
|
||||
# Fixtures for this format are created by placing text files in a sub-directory (with the name of the model) to the directory
|
||||
# appointed by <tt>ActiveSupport::TestCase.fixture_path=(path)</tt> (this is automatically configured for Rails, so you can just
|
||||
# put your files in <tt><your-rails-app>/test/fixtures/<your-model-name>/</tt> --
|
||||
# This type of fixture was the original format for Active Record that has since been deprecated in
|
||||
# favor of the YAML and CSV formats.
|
||||
# Fixtures for this format are created by placing text files in a sub-directory (with the name of the model)
|
||||
# to the directory appointed by <tt>ActiveSupport::TestCase.fixture_path=(path)</tt> (this is automatically
|
||||
# configured for Rails, so you can just put your files in <tt><your-rails-app>/test/fixtures/<your-model-name>/</tt> --
|
||||
# like <tt><your-rails-app>/test/fixtures/web_sites/</tt> for the WebSite model).
|
||||
#
|
||||
# Each text file placed in this directory represents a "record". Usually these types of fixtures are named without
|
||||
# extensions, but if you are on a Windows machine, you might consider adding <tt>.txt</tt> as the extension. Here's what the
|
||||
# above example might look like:
|
||||
# extensions, but if you are on a Windows machine, you might consider adding <tt>.txt</tt> as the extension.
|
||||
# Here's what the above example might look like:
|
||||
#
|
||||
# web_sites/google
|
||||
# web_sites/yahoo.txt
|
||||
@@ -133,7 +137,8 @@ end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# By default, the <tt>test_helper module</tt> will load all of your fixtures into your test database, so this test will succeed.
|
||||
# By default, the <tt>test_helper module</tt> will load all of your fixtures into your test database,
|
||||
# so this test will succeed.
|
||||
# The testing environment will automatically load the all fixtures into the database before each test.
|
||||
# To ensure consistent data, the environment deletes the fixtures before running the load.
|
||||
#
|
||||
@@ -182,13 +187,15 @@ end
|
||||
# This will create 1000 very simple YAML fixtures.
|
||||
#
|
||||
# Using ERb, you can also inject dynamic values into your fixtures with inserts like <tt><%= Date.today.strftime("%Y-%m-%d") %></tt>.
|
||||
# This is however a feature to be used with some caution. The point of fixtures are that they're stable units of predictable
|
||||
# sample data. If you feel that you need to inject dynamic values, then perhaps you should reexamine whether your application
|
||||
# is properly testable. Hence, dynamic values in fixtures are to be considered a code smell.
|
||||
# This is however a feature to be used with some caution. The point of fixtures are that they're
|
||||
# stable units of predictable sample data. If you feel that you need to inject dynamic values, then
|
||||
# perhaps you should reexamine whether your application is properly testable. Hence, dynamic values
|
||||
# in fixtures are to be considered a code smell.
|
||||
#
|
||||
# = Transactional fixtures
|
||||
#
|
||||
# TestCases can use begin+rollback to isolate their changes to the database instead of having to delete+insert for every test case.
|
||||
# TestCases can use begin+rollback to isolate their changes to the database instead of having to
|
||||
# delete+insert for every test case.
|
||||
#
|
||||
# class FooTest < ActiveSupport::TestCase
|
||||
# self.use_transactional_fixtures = true
|
||||
@@ -205,15 +212,18 @@ end
|
||||
# end
|
||||
#
|
||||
# If you preload your test database with all fixture data (probably in the Rakefile task) and use transactional fixtures,
|
||||
# then you may omit all fixtures declarations in your test cases since all the data's already there and every case rolls back its changes.
|
||||
# then you may omit all fixtures declarations in your test cases since all the data's already there
|
||||
# and every case rolls back its changes.
|
||||
#
|
||||
# In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to true. This will provide
|
||||
# access to fixture data for every table that has been loaded through fixtures (depending on the value of +use_instantiated_fixtures+)
|
||||
# access to fixture data for every table that has been loaded through fixtures (depending on the
|
||||
# value of +use_instantiated_fixtures+)
|
||||
#
|
||||
# When *not* to use transactional fixtures:
|
||||
#
|
||||
# 1. You're testing whether a transaction works correctly. Nested transactions don't commit until all parent transactions commit,
|
||||
# particularly, the fixtures transaction which is begun in setup and rolled back in teardown. Thus, you won't be able to verify
|
||||
# 1. You're testing whether a transaction works correctly. Nested transactions don't commit until
|
||||
# all parent transactions commit, particularly, the fixtures transaction which is begun in setup
|
||||
# and rolled back in teardown. Thus, you won't be able to verify
|
||||
# the results of your transaction until Active Record supports nested transactions or savepoints (in progress).
|
||||
# 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM.
|
||||
# Use InnoDB, MaxDB, or NDB instead.
|
||||
|
||||
@@ -48,18 +48,21 @@ module ActiveRecord
|
||||
# The above calls to <tt>scope</tt> define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red,
|
||||
# in effect, represents the query <tt>Shirt.where(:color => 'red')</tt>.
|
||||
#
|
||||
# Unlike <tt>Shirt.find(...)</tt>, however, the object returned by Shirt.red is not an Array; it resembles the association object
|
||||
# constructed by a <tt>has_many</tt> declaration. For instance, you can invoke <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>,
|
||||
# <tt>Shirt.red.where(:size => 'small')</tt>. Also, just as with the association objects, named \scopes act like an Array,
|
||||
# implementing Enumerable; <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt>
|
||||
# Unlike <tt>Shirt.find(...)</tt>, however, the object returned by Shirt.red is not an Array; it
|
||||
# resembles the association object constructed by a <tt>has_many</tt> declaration. For instance,
|
||||
# you can invoke <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>, <tt>Shirt.red.where(:size => 'small')</tt>.
|
||||
# Also, just as with the association objects, named \scopes act like an Array, implementing Enumerable;
|
||||
# <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt>
|
||||
# all behave as if Shirt.red really was an Array.
|
||||
#
|
||||
# These named \scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are both red and dry clean only.
|
||||
# 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>.
|
||||
# These named \scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce
|
||||
# all shirts that are both red and dry clean only.
|
||||
# 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 descendant upon which the \scopes were defined. But they are also available to
|
||||
# <tt>has_many</tt> associations. If,
|
||||
# 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
|
||||
# has_many :shirts
|
||||
|
||||
@@ -67,8 +67,8 @@ module ActiveRecord
|
||||
#
|
||||
# == Configuration
|
||||
#
|
||||
# In order to activate an observer, list it in the <tt>config.active_record.observers</tt> configuration setting in your
|
||||
# <tt>config/application.rb</tt> file.
|
||||
# In order to activate an observer, list it in the <tt>config.active_record.observers</tt> configuration
|
||||
# setting in your <tt>config/application.rb</tt> file.
|
||||
#
|
||||
# config.active_record.observers = :comment_observer, :signup_observer
|
||||
#
|
||||
|
||||
@@ -91,8 +91,8 @@ module ActiveRecord
|
||||
# like render <tt>:partial => @client.becomes(Company)</tt> to render that
|
||||
# instance using the companies/company partial instead of clients/client.
|
||||
#
|
||||
# Note: The new instance will share a link to the same attributes as the original class. So any change to the attributes in either
|
||||
# instance will affect the other.
|
||||
# Note: The new instance will share a link to the same attributes as the original class.
|
||||
# So any change to the attributes in either instance will affect the other.
|
||||
def becomes(klass)
|
||||
became = klass.new
|
||||
became.instance_variable_set("@attributes", @attributes)
|
||||
|
||||
@@ -67,7 +67,8 @@ module ActiveRecord
|
||||
preload += @includes_values unless eager_loading?
|
||||
preload.each {|associations| @klass.send(:preload_associations, @records, associations) }
|
||||
|
||||
# @readonly_value is true only if set explicitly. @implicit_readonly is true if there are JOINS and no explicit SELECT.
|
||||
# @readonly_value is true only if set explicitly. @implicit_readonly is true if there
|
||||
# are JOINS and no explicit SELECT.
|
||||
readonly = @readonly_value.nil? ? @implicit_readonly : @readonly_value
|
||||
@records.each { |record| record.readonly! } if readonly
|
||||
|
||||
@@ -130,7 +131,8 @@ module ActiveRecord
|
||||
# ==== Parameters
|
||||
#
|
||||
# * +updates+ - A string, array, or hash representing the SET part of an SQL statement.
|
||||
# * +conditions+ - A string, array, or hash representing the WHERE part of an SQL statement. See conditions in the intro.
|
||||
# * +conditions+ - A string, array, or hash representing the WHERE part of an SQL statement.
|
||||
# See conditions in the intro.
|
||||
# * +options+ - Additional options are <tt>:limit</tt> and <tt>:order</tt>, see the examples for usage.
|
||||
#
|
||||
# ==== Examples
|
||||
@@ -144,7 +146,7 @@ module ActiveRecord
|
||||
# # Update all avatars migrated more than a week ago
|
||||
# Avatar.update_all ['migrated_at = ?', Time.now.utc], ['migrated_at > ?', 1.week.ago]
|
||||
#
|
||||
# # Update all books that match our conditions, but limit it to 5 ordered by date
|
||||
# # Update all books that match conditions, but limit it to 5 ordered by date
|
||||
# Book.update_all "author = 'David'", "title LIKE '%Rails%'", :order => 'created_at', :limit => 5
|
||||
def update_all(updates, conditions = nil, options = {})
|
||||
if conditions || options.present?
|
||||
@@ -165,14 +167,14 @@ module ActiveRecord
|
||||
# ==== Parameters
|
||||
#
|
||||
# * +id+ - This should be the id or an array of ids to be updated.
|
||||
# * +attributes+ - This should be a hash of attributes to be set on the object, or an array of hashes.
|
||||
# * +attributes+ - This should be a hash of attributes or an array of hashes.
|
||||
#
|
||||
# ==== Examples
|
||||
#
|
||||
# # Updating one record:
|
||||
# # Updates one record
|
||||
# Person.update(15, :user_name => 'Samuel', :group => 'expert')
|
||||
#
|
||||
# # Updating multiple records:
|
||||
# # Updates multiple records
|
||||
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
|
||||
# Person.update(people.keys, people.values)
|
||||
def update(id, attributes)
|
||||
|
||||
@@ -5,26 +5,33 @@ module ActiveRecord
|
||||
# Count operates using three different approaches.
|
||||
#
|
||||
# * Count all: By not passing any parameters to count, it will return a count of all the rows for the model.
|
||||
# * Count using column: By passing a column name to count, it will return a count of all the rows for the model with supplied column present
|
||||
# * Count using column: By passing a column name to count, it will return a count of all the
|
||||
# rows for the model with supplied column present
|
||||
# * Count using options will find the row count matched by the options used.
|
||||
#
|
||||
# The third approach, count using options, accepts an option hash as the only parameter. The options are:
|
||||
#
|
||||
# * <tt>:conditions</tt>: An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro to ActiveRecord::Base.
|
||||
# * <tt>:conditions</tt>: An SQL fragment like "administrator = 1" or [ "user_name = ?", username ].
|
||||
# See conditions in the intro to ActiveRecord::Base.
|
||||
# * <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 INNER JOIN on the associated table(s).
|
||||
# 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.
|
||||
# or named associations in the same form used for the <tt>:include</tt> option, which will
|
||||
# perform an INNER JOIN on the associated table(s).
|
||||
# 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>: Named associations that should be loaded alongside using LEFT OUTER JOINs. The symbols named refer
|
||||
# to already defined associations. When using named associations, count returns the number of DISTINCT items for the model you're counting.
|
||||
# * <tt>:include</tt>: Named associations that should be loaded alongside using LEFT OUTER JOINs.
|
||||
# The symbols named refer to already defined associations. When using named associations, count
|
||||
# returns the number of DISTINCT items for the model you're counting.
|
||||
# See eager loading under Associations.
|
||||
# * <tt>:order</tt>: An SQL fragment like "created_at DESC, name" (really only used with GROUP BY calculations).
|
||||
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
|
||||
# * <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
|
||||
# * <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>:distinct</tt>: Set this to true to make this a distinct calculation, such as SELECT COUNT(DISTINCT posts.id) ...
|
||||
# * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
|
||||
# of a database view).
|
||||
# * <tt>:distinct</tt>: Set this to true to make this a distinct calculation, such as
|
||||
# SELECT COUNT(DISTINCT posts.id) ...
|
||||
# * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an
|
||||
# alternate table name (or even the name of a database view).
|
||||
#
|
||||
# Examples for counting all:
|
||||
# Person.count # returns the total count of all people
|
||||
@@ -34,12 +41,19 @@ module ActiveRecord
|
||||
#
|
||||
# Examples for count with options:
|
||||
# Person.count(:conditions => "age > 26")
|
||||
# Person.count(:conditions => "age > 26 AND job.salary > 60000", :include => :job) # because of the named association, it finds the DISTINCT count using LEFT OUTER JOIN.
|
||||
# Person.count(:conditions => "age > 26 AND job.salary > 60000", :joins => "LEFT JOIN jobs on jobs.person_id = person.id") # finds the number of rows matching the conditions and joins.
|
||||
#
|
||||
# # because of the named association, it finds the DISTINCT count using LEFT OUTER JOIN.
|
||||
# Person.count(:conditions => "age > 26 AND job.salary > 60000", :include => :job)
|
||||
#
|
||||
# # finds the number of rows matching the conditions and joins.
|
||||
# Person.count(:conditions => "age > 26 AND job.salary > 60000",
|
||||
# :joins => "LEFT JOIN jobs on jobs.person_id = person.id")
|
||||
#
|
||||
# Person.count('id', :conditions => "age > 26") # Performs a COUNT(id)
|
||||
# Person.count(:all, :conditions => "age > 26") # Performs a COUNT(*) (:all is an alias for '*')
|
||||
#
|
||||
# Note: <tt>Person.count(:all)</tt> will not work because it will use <tt>:all</tt> as the condition. Use Person.count instead.
|
||||
# Note: <tt>Person.count(:all)</tt> will not work because it will use <tt>:all</tt> as the condition.
|
||||
# Use Person.count instead.
|
||||
def count(column_name = nil, options = {})
|
||||
column_name, options = nil, column_name if column_name.is_a?(Hash)
|
||||
calculate(:count, column_name, options)
|
||||
@@ -80,13 +94,15 @@ module ActiveRecord
|
||||
calculate(:sum, column_name, options)
|
||||
end
|
||||
|
||||
# This calculates aggregate values in the given column. Methods for count, sum, average, minimum, and maximum have been added as shortcuts.
|
||||
# Options such as <tt>:conditions</tt>, <tt>:order</tt>, <tt>:group</tt>, <tt>:having</tt>, and <tt>:joins</tt> can be passed to customize the query.
|
||||
# This calculates aggregate values in the given column. Methods for count, sum, average,
|
||||
# minimum, and maximum have been added as shortcuts. Options such as <tt>:conditions</tt>,
|
||||
# <tt>:order</tt>, <tt>:group</tt>, <tt>:having</tt>, and <tt>:joins</tt> can be passed to customize the query.
|
||||
#
|
||||
# There are two basic forms of output:
|
||||
# * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float for AVG, and the given column's type for everything else.
|
||||
# * Grouped values: This returns an ordered hash of the values and groups them by the <tt>:group</tt> option. It takes either a column name, or the name
|
||||
# of a belongs_to association.
|
||||
# * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float
|
||||
# for AVG, and the given column's type for everything else.
|
||||
# * Grouped values: This returns an ordered hash of the values and groups them by the
|
||||
# <tt>:group</tt> option. It takes either a column name, or the name of a belongs_to association.
|
||||
#
|
||||
# values = Person.maximum(:age, :group => 'last_name')
|
||||
# puts values["Drake"]
|
||||
@@ -102,21 +118,30 @@ module ActiveRecord
|
||||
# end
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:conditions</tt> - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro to ActiveRecord::Base.
|
||||
# * <tt>:include</tt>: Eager loading, see Associations for details. Since calculations don't load anything, the purpose of this is to access fields on joined tables in your conditions, order, or group clauses.
|
||||
# * <tt>:joins</tt> - An SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id". (Rarely needed).
|
||||
# The records will be returned read-only since they will have attributes that do not correspond to the table's columns.
|
||||
# * <tt>:conditions</tt> - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ].
|
||||
# See conditions in the intro to ActiveRecord::Base.
|
||||
# * <tt>:include</tt>: Eager loading, see Associations for details. Since calculations don't load anything,
|
||||
# the purpose of this is to access fields on joined tables in your conditions, order, or group clauses.
|
||||
# * <tt>:joins</tt> - An SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id".
|
||||
# (Rarely needed).
|
||||
# The records will be returned read-only since they will have attributes that do not correspond to the
|
||||
# table's columns.
|
||||
# * <tt>:order</tt> - An SQL fragment like "created_at DESC, name" (really only used with GROUP BY calculations).
|
||||
# * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
|
||||
# * <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>:distinct</tt> - Set this to true to make this a distinct calculation, such as SELECT COUNT(DISTINCT posts.id) ...
|
||||
# * <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>:distinct</tt> - Set this to true to make this a distinct calculation, such as
|
||||
# SELECT COUNT(DISTINCT posts.id) ...
|
||||
#
|
||||
# Examples:
|
||||
# Person.calculate(:count, :all) # The same as Person.count
|
||||
# Person.average(:age) # SELECT AVG(age) FROM people...
|
||||
# Person.minimum(:age, :conditions => ['last_name != ?', 'Drake']) # Selects the minimum age for everyone with a last name other than 'Drake'
|
||||
# Person.minimum(:age, :having => 'min(age) > 17', :group => :last_name) # Selects the minimum age for any family without any minors
|
||||
# Person.minimum(:age, :conditions => ['last_name != ?', 'Drake']) # Selects the minimum age for
|
||||
# # everyone with a last name other than 'Drake'
|
||||
#
|
||||
# # Selects the minimum age for any family without any minors
|
||||
# Person.minimum(:age, :having => 'min(age) > 17', :group => :last_name)
|
||||
#
|
||||
# Person.sum("2 * age")
|
||||
def calculate(operation, column_name, options = {})
|
||||
if options.except(:distinct).present?
|
||||
|
||||
@@ -21,23 +21,28 @@ module ActiveRecord
|
||||
#
|
||||
# ==== Parameters
|
||||
#
|
||||
# * <tt>:conditions</tt> - An SQL fragment like "administrator = 1", <tt>[ "user_name = ?", username ]</tt>, or <tt>["user_name = :user_name", { :user_name => user_name }]</tt>. See conditions in the intro.
|
||||
# * <tt>:conditions</tt> - An SQL fragment like "administrator = 1", <tt>[ "user_name = ?", username ]</tt>,
|
||||
# or <tt>["user_name = :user_name", { :user_name => user_name }]</tt>. See conditions in the intro.
|
||||
# * <tt>:order</tt> - An SQL fragment like "created_at DESC, name".
|
||||
# * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
|
||||
# * <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>: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>: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),
|
||||
# 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),
|
||||
# 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.
|
||||
# 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
|
||||
# to already defined associations. See eager loading under Associations.
|
||||
# * <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. Takes a string with the SELECT SQL fragment (e.g. "id, name").
|
||||
# * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
|
||||
# of a database view).
|
||||
# * <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. Takes a string with the SELECT SQL fragment (e.g. "id, name").
|
||||
# * <tt>:from</tt> - By default, this is the table name of the class, but can be changed
|
||||
# to an alternate table name (or even the name of a database view).
|
||||
# * <tt>:readonly</tt> - Mark the returned records read-only so they cannot be saved or updated.
|
||||
# * <tt>:lock</tt> - An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE".
|
||||
# <tt>:lock => true</tt> gives connection's default exclusive lock, usually "FOR UPDATE".
|
||||
|
||||
@@ -21,7 +21,8 @@ module ActiveRecord
|
||||
#
|
||||
# This feature can easily be turned off by assigning value <tt>false</tt> .
|
||||
#
|
||||
# If your attributes are time zone aware and you desire to skip time zone conversion for certain attributes then you can do following:
|
||||
# If your attributes are time zone aware and you desire to skip time zone conversion for certain
|
||||
# attributes then you can do following:
|
||||
#
|
||||
# Topic.skip_time_zone_conversion_for_attributes = [:written_on]
|
||||
module Timestamp
|
||||
|
||||
@@ -27,8 +27,9 @@ module ActiveRecord
|
||||
#
|
||||
# this would specify a circular dependency and cause infinite recursion.
|
||||
#
|
||||
# NOTE: This validation will not fail if the association hasn't been assigned. If you want to ensure that the association
|
||||
# is both present and guaranteed to be valid, you also need to use +validates_presence_of+.
|
||||
# NOTE: This validation will not fail if the association hasn't been assigned. If you want to
|
||||
# ensure that the association is both present and guaranteed to be valid, you also need to
|
||||
# use +validates_presence_of+.
|
||||
#
|
||||
# Configuration options:
|
||||
# * <tt>:message</tt> - A custom error message (default is: "is invalid")
|
||||
@@ -44,4 +45,4 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -78,22 +78,25 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Validates whether the value of the specified attributes are unique across the system. Useful for making sure that only one user
|
||||
# Validates whether the value of the specified attributes are unique across the system.
|
||||
# Useful for making sure that only one user
|
||||
# can be named "davidhh".
|
||||
#
|
||||
# class Person < ActiveRecord::Base
|
||||
# validates_uniqueness_of :user_name, :scope => :account_id
|
||||
# end
|
||||
#
|
||||
# It can also validate whether the value of the specified attributes are unique based on multiple scope parameters. For example,
|
||||
# making sure that a teacher can only be on the schedule once per semester for a particular class.
|
||||
# It can also validate whether the value of the specified attributes are unique based on multiple
|
||||
# scope parameters. For example, making sure that a teacher can only be on the schedule once
|
||||
# per semester for a particular class.
|
||||
#
|
||||
# class TeacherSchedule < ActiveRecord::Base
|
||||
# validates_uniqueness_of :teacher_id, :scope => [:semester_id, :class_id]
|
||||
# end
|
||||
#
|
||||
# When the record is created, a check is performed to make sure that no record exists in the database with the given value for the specified
|
||||
# attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself.
|
||||
# When the record is created, a check is performed to make sure that no record exists in the database
|
||||
# with the given value for the specified attribute (that maps to a column). When the record is updated,
|
||||
# the same check is made but disregarding the record itself.
|
||||
#
|
||||
# Configuration options:
|
||||
# * <tt>:message</tt> - Specifies a custom error message (default is: "has already been taken").
|
||||
@@ -102,11 +105,12 @@ module ActiveRecord
|
||||
# * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
|
||||
# * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
|
||||
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
|
||||
# The method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or
|
||||
# <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The method, proc or string should
|
||||
# return or evaluate to a true or false value.
|
||||
#
|
||||
# === Concurrency and integrity
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user