activerecord 3.0.0.rc → 3.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (55) hide show
  1. data/CHANGELOG +6 -1
  2. data/README.rdoc +9 -9
  3. data/lib/active_record/aggregations.rb +64 -51
  4. data/lib/active_record/association_preload.rb +11 -9
  5. data/lib/active_record/associations.rb +300 -204
  6. data/lib/active_record/associations/association_collection.rb +7 -2
  7. data/lib/active_record/associations/belongs_to_association.rb +9 -5
  8. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +7 -6
  9. data/lib/active_record/associations/has_many_association.rb +6 -6
  10. data/lib/active_record/associations/has_many_through_association.rb +4 -3
  11. data/lib/active_record/associations/has_one_association.rb +7 -7
  12. data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -1
  13. data/lib/active_record/attribute_methods/write.rb +2 -2
  14. data/lib/active_record/autosave_association.rb +54 -72
  15. data/lib/active_record/base.rb +167 -108
  16. data/lib/active_record/callbacks.rb +43 -35
  17. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +8 -11
  18. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -1
  19. data/lib/active_record/connection_adapters/abstract/query_cache.rb +0 -8
  20. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  21. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +8 -6
  22. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +5 -3
  23. data/lib/active_record/connection_adapters/mysql_adapter.rb +5 -1
  24. data/lib/active_record/connection_adapters/postgresql_adapter.rb +9 -5
  25. data/lib/active_record/connection_adapters/sqlite_adapter.rb +5 -5
  26. data/lib/active_record/dynamic_finder_match.rb +3 -3
  27. data/lib/active_record/dynamic_scope_match.rb +1 -1
  28. data/lib/active_record/errors.rb +9 -5
  29. data/lib/active_record/fixtures.rb +36 -22
  30. data/lib/active_record/locale/en.yml +2 -2
  31. data/lib/active_record/migration.rb +36 -36
  32. data/lib/active_record/named_scope.rb +23 -11
  33. data/lib/active_record/nested_attributes.rb +3 -3
  34. data/lib/active_record/observer.rb +3 -3
  35. data/lib/active_record/persistence.rb +44 -29
  36. data/lib/active_record/railtie.rb +5 -8
  37. data/lib/active_record/railties/databases.rake +1 -1
  38. data/lib/active_record/reflection.rb +52 -52
  39. data/lib/active_record/relation.rb +26 -19
  40. data/lib/active_record/relation/batches.rb +4 -4
  41. data/lib/active_record/relation/calculations.rb +58 -34
  42. data/lib/active_record/relation/finder_methods.rb +21 -12
  43. data/lib/active_record/relation/query_methods.rb +26 -31
  44. data/lib/active_record/relation/spawn_methods.rb +17 -5
  45. data/lib/active_record/schema.rb +1 -1
  46. data/lib/active_record/schema_dumper.rb +12 -12
  47. data/lib/active_record/serialization.rb +1 -1
  48. data/lib/active_record/serializers/xml_serializer.rb +1 -1
  49. data/lib/active_record/session_store.rb +9 -9
  50. data/lib/active_record/test_case.rb +2 -2
  51. data/lib/active_record/timestamp.rb +31 -32
  52. data/lib/active_record/validations/associated.rb +4 -3
  53. data/lib/active_record/validations/uniqueness.rb +15 -11
  54. data/lib/active_record/version.rb +1 -1
  55. metadata +17 -16
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ *Rails 3.0.0 [release candidate 2] (August 23rd, 2010)*
2
+
3
+ * No material changes (see http://github.com/rails/rails/compare/v3.0.0_RC...v3.0.0_RC2 for gory details)
4
+
5
+
1
6
  *Rails 3.0.0 [release candidate] (July 26th, 2010)*
2
7
 
3
8
  * Changed update_attribute to not run callbacks and update the record directly in the database [Neeraj Singh]
@@ -966,7 +971,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing]
966
971
  * Made increment_counter/decrement_counter play nicely with optimistic locking, and added a more general update_counters method [Jamis Buck]
967
972
 
968
973
  * Reworked David's query cache to be available as Model.cache {...}. For the duration of the block no select query should be run more then once. Any inserts/deletes/executes will flush the whole cache however [Tobias Lütke]
969
- Task.cache { Task.find(1); Task.find(1) } #=> 1 query
974
+ Task.cache { Task.find(1); Task.find(1) } # => 1 query
970
975
 
971
976
  * When dealing with SQLite3, use the table_info pragma helper, so that the bindings can do some translation for when sqlite3 breaks incompatibly between point releases. [Jamis Buck]
972
977
 
@@ -19,19 +19,19 @@ A short rundown of some of the major features:
19
19
 
20
20
  class Product < ActiveRecord::Base
21
21
  end
22
-
22
+
23
23
  The Product class is automatically mapped to the table named "products",
24
24
  which might look like this:
25
-
25
+
26
26
  CREATE TABLE products (
27
27
  id int(11) NOT NULL auto_increment,
28
28
  name varchar(255),
29
29
  PRIMARY KEY (id)
30
30
  );
31
-
31
+
32
32
  This would also define the following accessors: `Product#name` and
33
33
  `Product#name=(new_name)`
34
-
34
+
35
35
  {Learn more}[link:classes/ActiveRecord/Base.html]
36
36
 
37
37
 
@@ -51,7 +51,7 @@ A short rundown of some of the major features:
51
51
  class Account < ActiveRecord::Base
52
52
  composed_of :balance, :class_name => "Money",
53
53
  :mapping => %w(balance amount)
54
- composed_of :address,
54
+ composed_of :address,
55
55
  :mapping => [%w(address_street street), %w(address_city city)]
56
56
  end
57
57
 
@@ -91,7 +91,7 @@ A short rundown of some of the major features:
91
91
  {Learn more}[link:classes/ActiveRecord/Observer.html]
92
92
 
93
93
 
94
- * Inheritance hierarchies
94
+ * Inheritance hierarchies
95
95
 
96
96
  class Company < ActiveRecord::Base; end
97
97
  class Firm < Company; end
@@ -170,7 +170,7 @@ A short rundown of some of the major features:
170
170
  {Learn more}[link:classes/ActiveRecord/Migration.html]
171
171
 
172
172
 
173
- == Philosophy
173
+ == Philosophy
174
174
 
175
175
  Active Record is an implementation of the object-relational mapping (ORM)
176
176
  pattern[http://www.martinfowler.com/eaaCatalog/activeRecord.html] by the same
@@ -179,7 +179,7 @@ name described by Martin Fowler:
179
179
  "An object that wraps a row in a database table or view,
180
180
  encapsulates the database access, and adds domain logic on that data."
181
181
 
182
- Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is
182
+ Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is
183
183
  object-relational mapping. The prime directive for this mapping has been to minimize
184
184
  the amount of code needed to build a real-world domain model. This is made possible
185
185
  by relying on a number of conventions that make it easy for Active Record to infer
@@ -188,7 +188,7 @@ complex relations and structures from a minimal amount of explicit direction.
188
188
  Convention over Configuration:
189
189
  * No XML-files!
190
190
  * Lots of reflection and run-time extension
191
- * Magic is not inherently a bad word
191
+ * Magic is not inherently a bad word
192
192
 
193
193
  Admit the Database:
194
194
  * Lets you drop down to SQL for odd cases and performance
@@ -9,11 +9,13 @@ module ActiveRecord
9
9
  end unless self.new_record?
10
10
  end
11
11
 
12
- # Active Record implements aggregation through a macro-like class method called +composed_of+ for representing attributes
13
- # as value objects. It expresses relationships like "Account [is] composed of Money [among other things]" or "Person [is]
14
- # composed of [an] address". Each call to the macro adds a description of how the value objects are created from the
15
- # attributes of the entity object (when the entity is initialized either as a new object or from finding an existing object)
16
- # and how it can be turned back into attributes (when the entity is saved to the database). Example:
12
+ # Active Record implements aggregation through a macro-like class method called +composed_of+
13
+ # for representing attributes as value objects. It expresses relationships like "Account [is]
14
+ # composed of Money [among other things]" or "Person [is] composed of [an] address". Each call
15
+ # to the macro adds a description of how the value objects are created from the attributes of
16
+ # the entity object (when the entity is initialized either as a new object or from finding an
17
+ # existing object) and how it can be turned back into attributes (when the entity is saved to
18
+ # the database).
17
19
  #
18
20
  # class Customer < ActiveRecord::Base
19
21
  # composed_of :balance, :class_name => "Money", :mapping => %w(balance amount)
@@ -68,9 +70,10 @@ module ActiveRecord
68
70
  # end
69
71
  # end
70
72
  #
71
- # Now it's possible to access attributes from the database through the value objects instead. If you choose to name the
72
- # composition the same as the attribute's name, it will be the only way to access that attribute. That's the case with our
73
- # +balance+ attribute. You interact with the value objects just like you would any other attribute, though:
73
+ # Now it's possible to access attributes from the database through the value objects instead. If
74
+ # you choose to name the composition the same as the attribute's name, it will be the only way to
75
+ # access that attribute. That's the case with our +balance+ attribute. You interact with the value
76
+ # objects just like you would any other attribute, though:
74
77
  #
75
78
  # customer.balance = Money.new(20) # sets the Money value object and the attribute
76
79
  # customer.balance # => Money value object
@@ -79,8 +82,8 @@ module ActiveRecord
79
82
  # customer.balance == Money.new(20) # => true
80
83
  # customer.balance < Money.new(5) # => false
81
84
  #
82
- # Value objects can also be composed of multiple attributes, such as the case of Address. The order of the mappings will
83
- # determine the order of the parameters. Example:
85
+ # Value objects can also be composed of multiple attributes, such as the case of Address. The order
86
+ # of the mappings will determine the order of the parameters.
84
87
  #
85
88
  # customer.address_street = "Hyancintvej"
86
89
  # customer.address_city = "Copenhagen"
@@ -91,38 +94,43 @@ module ActiveRecord
91
94
  #
92
95
  # == Writing value objects
93
96
  #
94
- # Value objects are immutable and interchangeable objects that represent a given value, such as a Money object representing
95
- # $5. Two Money objects both representing $5 should be equal (through methods such as <tt>==</tt> and <tt><=></tt> from Comparable if ranking
96
- # makes sense). This is unlike entity objects where equality is determined by identity. An entity class such as Customer can
97
- # easily have two different objects that both have an address on Hyancintvej. Entity identity is determined by object or
98
- # relational unique identifiers (such as primary keys). Normal ActiveRecord::Base classes are entity objects.
97
+ # Value objects are immutable and interchangeable objects that represent a given value, such as
98
+ # a Money object representing $5. Two Money objects both representing $5 should be equal (through
99
+ # methods such as <tt>==</tt> and <tt><=></tt> from Comparable if ranking makes sense). This is
100
+ # unlike entity objects where equality is determined by identity. An entity class such as Customer can
101
+ # easily have two different objects that both have an address on Hyancintvej. Entity identity is
102
+ # determined by object or relational unique identifiers (such as primary keys). Normal
103
+ # ActiveRecord::Base classes are entity objects.
99
104
  #
100
- # It's also important to treat the value objects as immutable. Don't allow the Money object to have its amount changed after
101
- # creation. Create a new Money object with the new value instead. This is exemplified by the Money#exchange_to method that
102
- # returns a new value object instead of changing its own values. Active Record won't persist value objects that have been
103
- # changed through means other than the writer method.
105
+ # It's also important to treat the value objects as immutable. Don't allow the Money object to have
106
+ # its amount changed after creation. Create a new Money object with the new value instead. This
107
+ # is exemplified by the Money#exchange_to method that returns a new value object instead of changing
108
+ # its own values. Active Record won't persist value objects that have been changed through means
109
+ # other than the writer method.
104
110
  #
105
- # The immutable requirement is enforced by Active Record by freezing any object assigned as a value object. Attempting to
106
- # change it afterwards will result in a ActiveSupport::FrozenObjectError.
111
+ # The immutable requirement is enforced by Active Record by freezing any object assigned as a value
112
+ # object. Attempting to change it afterwards will result in a ActiveSupport::FrozenObjectError.
107
113
  #
108
- # Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not keeping value objects
109
- # immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable
114
+ # Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not
115
+ # keeping value objects immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable
110
116
  #
111
117
  # == Custom constructors and converters
112
118
  #
113
- # By default value objects are initialized by calling the <tt>new</tt> constructor of the value class passing each of the
114
- # mapped attributes, in the order specified by the <tt>:mapping</tt> option, as arguments. If the value class doesn't support
115
- # this convention then +composed_of+ allows a custom constructor to be specified.
119
+ # By default value objects are initialized by calling the <tt>new</tt> constructor of the value
120
+ # class passing each of the mapped attributes, in the order specified by the <tt>:mapping</tt>
121
+ # option, as arguments. If the value class doesn't support this convention then +composed_of+ allows
122
+ # a custom constructor to be specified.
116
123
  #
117
- # When a new value is assigned to the value object the default assumption is that the new value is an instance of the value
118
- # class. Specifying a custom converter allows the new value to be automatically converted to an instance of value class if
119
- # necessary.
124
+ # When a new value is assigned to the value object the default assumption is that the new value
125
+ # is an instance of the value class. Specifying a custom converter allows the new value to be automatically
126
+ # converted to an instance of value class if necessary.
120
127
  #
121
- # For example, the NetworkResource model has +network_address+ and +cidr_range+ attributes that should be aggregated using the
122
- # NetAddr::CIDR value class (http://netaddr.rubyforge.org). The constructor for the value class is called +create+ and it
123
- # expects a CIDR address string as a parameter. New values can be assigned to the value object using either another
124
- # NetAddr::CIDR object, a string or an array. The <tt>:constructor</tt> and <tt>:converter</tt> options can be used to
125
- # meet these requirements:
128
+ # For example, the NetworkResource model has +network_address+ and +cidr_range+ attributes that
129
+ # should be aggregated using the NetAddr::CIDR value class (http://netaddr.rubyforge.org). The constructor
130
+ # for the value class is called +create+ and it expects a CIDR address string as a parameter. New
131
+ # values can be assigned to the value object using either another NetAddr::CIDR object, a string
132
+ # or an array. The <tt>:constructor</tt> and <tt>:converter</tt> options can be used to meet
133
+ # these requirements:
126
134
  #
127
135
  # class NetworkResource < ActiveRecord::Base
128
136
  # composed_of :cidr,
@@ -149,9 +157,9 @@ module ActiveRecord
149
157
  #
150
158
  # == Finding records by a value object
151
159
  #
152
- # Once a +composed_of+ relationship is specified for a model, records can be loaded from the database by specifying an instance
153
- # of the value object in the conditions hash. The following example finds all customers with +balance_amount+ equal to 20 and
154
- # +balance_currency+ equal to "USD":
160
+ # Once a +composed_of+ relationship is specified for a model, records can be loaded from the database
161
+ # by specifying an instance of the value object in the conditions hash. The following example
162
+ # finds all customers with +balance_amount+ equal to 20 and +balance_currency+ equal to "USD":
155
163
  #
156
164
  # Customer.find(:all, :conditions => {:balance => Money.new(20, "USD")})
157
165
  #
@@ -160,23 +168,28 @@ module ActiveRecord
160
168
  # <tt>composed_of :address</tt> adds <tt>address</tt> and <tt>address=(new_address)</tt> methods.
161
169
  #
162
170
  # Options are:
163
- # * <tt>:class_name</tt> - Specifies the class name of the association. Use it only if that name can't be inferred
164
- # from the part id. So <tt>composed_of :address</tt> will by default be linked to the Address class, but
165
- # if the real class name is CompanyAddress, you'll have to specify it with this option.
166
- # * <tt>:mapping</tt> - Specifies the mapping of entity attributes to attributes of the value object. Each mapping
167
- # is represented as an array where the first item is the name of the entity attribute and the second item is the
168
- # name the attribute in the value object. The order in which mappings are defined determine the order in which
169
- # attributes are sent to the value class constructor.
171
+ # * <tt>:class_name</tt> - Specifies the class name of the association. Use it only if that name
172
+ # can't be inferred from the part id. So <tt>composed_of :address</tt> will by default be linked
173
+ # to the Address class, but if the real class name is CompanyAddress, you'll have to specify it
174
+ # with this option.
175
+ # * <tt>:mapping</tt> - Specifies the mapping of entity attributes to attributes of the value
176
+ # object. Each mapping is represented as an array where the first item is the name of the
177
+ # entity attribute and the second item is the name the attribute in the value object. The
178
+ # order in which mappings are defined determine the order in which attributes are sent to the
179
+ # value class constructor.
170
180
  # * <tt>:allow_nil</tt> - Specifies that the value object will not be instantiated when all mapped
171
- # attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all mapped attributes.
181
+ # attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all
182
+ # mapped attributes.
172
183
  # This defaults to +false+.
173
- # * <tt>:constructor</tt> - A symbol specifying the name of the constructor method or a Proc that is called to
174
- # initialize the value object. The constructor is passed all of the mapped attributes, in the order that they
175
- # are defined in the <tt>:mapping option</tt>, as arguments and uses them to instantiate a <tt>:class_name</tt> object.
184
+ # * <tt>:constructor</tt> - A symbol specifying the name of the constructor method or a Proc that
185
+ # is called to initialize the value object. The constructor is passed all of the mapped attributes,
186
+ # in the order that they are defined in the <tt>:mapping option</tt>, as arguments and uses them
187
+ # to instantiate a <tt>:class_name</tt> object.
176
188
  # The default is <tt>:new</tt>.
177
- # * <tt>:converter</tt> - A symbol specifying the name of a class method of <tt>:class_name</tt> or a Proc that is
178
- # called when a new value is assigned to the value object. The converter is passed the single value that is used
179
- # in the assignment and is only called if the new value is not an instance of <tt>:class_name</tt>.
189
+ # * <tt>:converter</tt> - A symbol specifying the name of a class method of <tt>:class_name</tt>
190
+ # or a Proc that is called when a new value is assigned to the value object. The converter is
191
+ # passed the single value that is used in the assignment and is only called if the new value is
192
+ # not an instance of <tt>:class_name</tt>.
180
193
  #
181
194
  # Option examples:
182
195
  # composed_of :temperature, :mapping => %w(reading celsius)
@@ -9,8 +9,8 @@ module ActiveRecord
9
9
  # Implements the details of eager loading of Active Record associations.
10
10
  # Application developers should not use this module directly.
11
11
  #
12
- # ActiveRecord::Base is extended with this module. The source code in
13
- # ActiveRecord::Base references methods defined in this module.
12
+ # <tt>ActiveRecord::Base</tt> is extended with this module. The source code in
13
+ # <tt>ActiveRecord::Base</tt> references methods defined in this module.
14
14
  #
15
15
  # Note that 'eager loading' and 'preloading' are actually the same thing.
16
16
  # However, there are two different eager loading strategies.
@@ -55,7 +55,7 @@ module ActiveRecord
55
55
  # == Parameters
56
56
  # +records+ is an array of ActiveRecord::Base. This array needs not be flat,
57
57
  # i.e. +records+ itself may also contain arrays of records. In any case,
58
- # +preload_associations+ will preload the associations all records by
58
+ # +preload_associations+ will preload the all associations records by
59
59
  # flattening +records+.
60
60
  #
61
61
  # +associations+ specifies one or more associations that you want to
@@ -110,8 +110,8 @@ module ActiveRecord
110
110
  def preload_one_association(records, association, preload_options={})
111
111
  class_to_reflection = {}
112
112
  # Not all records have the same class, so group then preload
113
- # group on the reflection itself so that if various subclass share the same association then we do not split them
114
- # unnecessarily
113
+ # group on the reflection itself so that if various subclass share the same association then
114
+ # we do not split them unnecessarily
115
115
  records.group_by { |record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, _records|
116
116
  raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection
117
117
 
@@ -149,7 +149,8 @@ module ActiveRecord
149
149
  seen_keys = {}
150
150
  associated_records.each do |associated_record|
151
151
  #this is a has_one or belongs_to: there should only be one record.
152
- #Unfortunately we can't (in portable way) ask the database for 'all records where foo_id in (x,y,z), but please
152
+ #Unfortunately we can't (in portable way) ask the database for
153
+ #'all records where foo_id in (x,y,z), but please
153
154
  # only one row per distinct foo_id' so this where we enforce that
154
155
  next if seen_keys[associated_record[key].to_s]
155
156
  seen_keys[associated_record[key].to_s] = true
@@ -162,7 +163,7 @@ module ActiveRecord
162
163
 
163
164
  id_to_record_map.each do |id, records|
164
165
  next if seen_keys.include?(id.to_s)
165
- records.each {|record| record.send("set_#{reflection_name}_target", nil) }
166
+ records.each {|record| record.send("set_#{reflection_name}_target", nil) }
166
167
  end
167
168
  end
168
169
 
@@ -304,7 +305,8 @@ module ActiveRecord
304
305
  polymorph_type = options[:foreign_type]
305
306
  klasses_and_ids = {}
306
307
 
307
- # Construct a mapping from klass to a list of ids to load and a mapping of those ids back to their parent_records
308
+ # Construct a mapping from klass to a list of ids to load and a mapping of those ids back
309
+ # to their parent_records
308
310
  records.each do |record|
309
311
  if klass = record.send(polymorph_type)
310
312
  klass_id = record.send(primary_key_name)
@@ -370,7 +372,7 @@ module ActiveRecord
370
372
  conditions << append_conditions(reflection, preload_options)
371
373
 
372
374
  find_options = {
373
- :select => preload_options[:select] || options[:select] || "#{table_name}.*",
375
+ :select => preload_options[:select] || options[:select] || Arel::SqlLiteral.new("#{table_name}.*"),
374
376
  :include => preload_options[:include] || options[:include],
375
377
  :conditions => [conditions, ids],
376
378
  :joins => options[:joins],
@@ -35,7 +35,7 @@ module ActiveRecord
35
35
  through_reflection = reflection.through_reflection
36
36
  source_reflection_names = reflection.source_reflection_names
37
37
  source_associations = reflection.through_reflection.klass.reflect_on_all_associations.collect { |a| a.name.inspect }
38
- super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?")
38
+ super("Could not find the source association(s) #{source_reflection_names.collect{ |a| a.inspect }.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?")
39
39
  end
40
40
  end
41
41
 
@@ -114,7 +114,7 @@ module ActiveRecord
114
114
  autoload :HasOneAssociation, 'active_record/associations/has_one_association'
115
115
  autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association'
116
116
 
117
- # Clears out the association cache
117
+ # Clears out the association cache.
118
118
  def clear_association_cache #:nodoc:
119
119
  self.class.reflect_on_all_associations.to_a.each do |assoc|
120
120
  instance_variable_set "@#{assoc.name}", nil
@@ -122,7 +122,7 @@ module ActiveRecord
122
122
  end
123
123
 
124
124
  private
125
- # Gets the specified association instance if it responds to :loaded?, nil otherwise.
125
+ # Returns the specified association instance if it responds to :loaded?, nil otherwise.
126
126
  def association_instance_get(name)
127
127
  ivar = "@#{name}"
128
128
  if instance_variable_defined?(ivar)
@@ -136,10 +136,12 @@ module ActiveRecord
136
136
  instance_variable_set("@#{name}", association)
137
137
  end
138
138
 
139
- # Associations are a set of macro-like class methods for tying objects together through foreign keys. They express relationships like
140
- # "Project has one Project Manager" or "Project belongs to a Portfolio". Each macro adds a number of methods to the class which are
141
- # 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>
142
- # methods. Example:
139
+ # Associations are a set of macro-like class methods for tying objects together through
140
+ # foreign keys. They express relationships like "Project has one Project Manager"
141
+ # or "Project belongs to a Portfolio". Each macro adds a number of methods to the
142
+ # class which are specialized according to the collection or association symbol and the
143
+ # options hash. It works much the same way as Ruby's own <tt>attr*</tt>
144
+ # methods.
143
145
  #
144
146
  # class Project < ActiveRecord::Base
145
147
  # belongs_to :portfolio
@@ -148,7 +150,8 @@ module ActiveRecord
148
150
  # has_and_belongs_to_many :categories
149
151
  # end
150
152
  #
151
- # The project class now has the following methods (and more) to ease the traversal and manipulation of its relationships:
153
+ # The project class now has the following methods (and more) to ease the traversal and
154
+ # manipulation of its relationships:
152
155
  # * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt>
153
156
  # * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt>
154
157
  # * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt>
@@ -159,8 +162,9 @@ module ActiveRecord
159
162
  #
160
163
  # === A word of warning
161
164
  #
162
- # Don't create associations that have the same name as instance methods of ActiveRecord::Base. Since the association
163
- # adds a method with that name to its model, it will override the inherited method and break things.
165
+ # Don't create associations that have the same name as instance methods of
166
+ # <tt>ActiveRecord::Base</tt>. Since the association adds a method with that name to
167
+ # its model, it will override the inherited method and break things.
164
168
  # For instance, +attributes+ and +connection+ would be bad choices for association names.
165
169
  #
166
170
  # == Auto-generated methods
@@ -270,8 +274,8 @@ module ActiveRecord
270
274
  #
271
275
  # == Is it a +belongs_to+ or +has_one+ association?
272
276
  #
273
- # Both express a 1-1 relationship. The difference is mostly where to place the foreign key, which goes on the table for the class
274
- # declaring the +belongs_to+ relationship. Example:
277
+ # Both express a 1-1 relationship. The difference is mostly where to place the foreign
278
+ # key, which goes on the table for the class declaring the +belongs_to+ relationship.
275
279
  #
276
280
  # class User < ActiveRecord::Base
277
281
  # # I reference an account.
@@ -300,36 +304,45 @@ module ActiveRecord
300
304
  #
301
305
  # == Unsaved objects and associations
302
306
  #
303
- # You can manipulate objects and associations before they are saved to the database, but there is some special behavior you should be
304
- # aware of, mostly involving the saving of associated objects.
307
+ # You can manipulate objects and associations before they are saved to the database, but
308
+ # there is some special behavior you should be aware of, mostly involving the saving of
309
+ # associated objects.
305
310
  #
306
- # Unless you set the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
311
+ # You can set the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
307
312
  # <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association. Setting it
308
313
  # to +true+ will _always_ save the members, whereas setting it to +false+ will
309
- # _never_ save the members.
314
+ # _never_ save the members. More details about :autosave option is available at
315
+ # autosave_association.rb .
310
316
  #
311
317
  # === One-to-one associations
312
318
  #
313
- # * Assigning an object to a +has_one+ association automatically saves that object and the object being replaced (if there is one), in
314
- # order to update their primary keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
315
- # * If either of these saves fail (due to one of the objects being invalid) the assignment statement returns +false+ and the assignment
316
- # is cancelled.
317
- # * If you wish to assign an object to a +has_one+ association without saving it, use the <tt>association.build</tt> method (documented below).
318
- # * Assigning an object to a +belongs_to+ association does not save the object, since the foreign key field belongs on the parent. It
319
- # does not save the parent either.
319
+ # * Assigning an object to a +has_one+ association automatically saves that object and
320
+ # the object being replaced (if there is one), in order to update their primary
321
+ # keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
322
+ # * If either of these saves fail (due to one of the objects being invalid) the assignment
323
+ # statement returns +false+ and the assignment is cancelled.
324
+ # * If you wish to assign an object to a +has_one+ association without saving it,
325
+ # use the <tt>association.build</tt> method (documented below).
326
+ # * Assigning an object to a +belongs_to+ association does not save the object, since
327
+ # the foreign key field belongs on the parent. It does not save the parent either.
320
328
  #
321
329
  # === Collections
322
330
  #
323
- # * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically saves that object, except if the parent object
324
- # (the owner of the collection) is not yet stored in the database.
325
- # * If saving any of the objects being added to a collection (via <tt>push</tt> or similar) fails, then <tt>push</tt> returns +false+.
326
- # * You can add an object to a collection without automatically saving it by using the <tt>collection.build</tt> method (documented below).
327
- # * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically saved when the parent is saved.
331
+ # * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically
332
+ # saves that object, except if the parent object (the owner of the collection) is not yet
333
+ # stored in the database.
334
+ # * If saving any of the objects being added to a collection (via <tt>push</tt> or similar)
335
+ # fails, then <tt>push</tt> returns +false+.
336
+ # * You can add an object to a collection without automatically saving it by using the
337
+ # <tt>collection.build</tt> method (documented below).
338
+ # * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically
339
+ # saved when the parent is saved.
328
340
  #
329
341
  # === Association callbacks
330
342
  #
331
- # Similar to the normal callbacks that hook into the lifecycle of an Active Record object, you can also define callbacks that get
332
- # triggered when you add an object to or remove an object from an association collection. Example:
343
+ # Similar to the normal callbacks that hook into the lifecycle of an Active Record object,
344
+ # you can also define callbacks that get triggered when you add an object to or remove an
345
+ # object from an association collection.
333
346
  #
334
347
  # class Project
335
348
  # has_and_belongs_to_many :developers, :after_add => :evaluate_velocity
@@ -342,19 +355,21 @@ module ActiveRecord
342
355
  # It's possible to stack callbacks by passing them as an array. Example:
343
356
  #
344
357
  # class Project
345
- # has_and_belongs_to_many :developers, :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
358
+ # has_and_belongs_to_many :developers,
359
+ # :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
346
360
  # end
347
361
  #
348
362
  # Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
349
363
  #
350
- # Should any of the +before_add+ callbacks throw an exception, the object does not get added to the collection. Same with
351
- # the +before_remove+ callbacks; if an exception is thrown the object doesn't get removed.
364
+ # Should any of the +before_add+ callbacks throw an exception, the object does not get
365
+ # added to the collection. Same with the +before_remove+ callbacks; if an exception is
366
+ # thrown the object doesn't get removed.
352
367
  #
353
368
  # === Association extensions
354
369
  #
355
- # The proxy objects that control the access to associations can be extended through anonymous modules. This is especially
356
- # beneficial for adding new finders, creators, and other factory-type methods that are only used as part of this association.
357
- # Example:
370
+ # The proxy objects that control the access to associations can be extended through anonymous
371
+ # modules. This is especially beneficial for adding new finders, creators, and other
372
+ # factory-type methods that are only used as part of this association.
358
373
  #
359
374
  # class Account < ActiveRecord::Base
360
375
  # has_many :people do
@@ -369,7 +384,8 @@ module ActiveRecord
369
384
  # person.first_name # => "David"
370
385
  # person.last_name # => "Heinemeier Hansson"
371
386
  #
372
- # If you need to share the same extensions between many associations, you can use a named extension module. Example:
387
+ # If you need to share the same extensions between many associations, you can use a named
388
+ # extension module.
373
389
  #
374
390
  # module FindOrCreateByNameExtension
375
391
  # def find_or_create_by_name(name)
@@ -386,9 +402,10 @@ module ActiveRecord
386
402
  # has_many :people, :extend => FindOrCreateByNameExtension
387
403
  # end
388
404
  #
389
- # If you need to use multiple named extension modules, you can specify an array of modules with the <tt>:extend</tt> option.
390
- # In the case of name conflicts between methods in the modules, methods in modules later in the array supercede
391
- # those earlier in the array. Example:
405
+ # If you need to use multiple named extension modules, you can specify an array of modules
406
+ # with the <tt>:extend</tt> option.
407
+ # In the case of name conflicts between methods in the modules, methods in modules later
408
+ # in the array supercede those earlier in the array.
392
409
  #
393
410
  # class Account < ActiveRecord::Base
394
411
  # has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
@@ -399,12 +416,14 @@ module ActiveRecord
399
416
  #
400
417
  # * +proxy_owner+ - Returns the object the association is part of.
401
418
  # * +proxy_reflection+ - Returns the reflection object that describes the association.
402
- # * +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+.
419
+ # * +proxy_target+ - Returns the associated object for +belongs_to+ and +has_one+, or
420
+ # the collection of associated objects for +has_many+ and +has_and_belongs_to_many+.
403
421
  #
404
422
  # === Association Join Models
405
423
  #
406
- # Has Many associations can be configured with the <tt>:through</tt> option to use an explicit join model to retrieve the data. This
407
- # operates similarly to a +has_and_belongs_to_many+ association. The advantage is that you're able to add validations,
424
+ # Has Many associations can be configured with the <tt>:through</tt> option to use an
425
+ # explicit join model to retrieve the data. This operates similarly to a
426
+ # +has_and_belongs_to_many+ association. The advantage is that you're able to add validations,
408
427
  # callbacks, and extra attributes on the join model. Consider the following schema:
409
428
  #
410
429
  # class Author < ActiveRecord::Base
@@ -418,7 +437,7 @@ module ActiveRecord
418
437
  # end
419
438
  #
420
439
  # @author = Author.find :first
421
- # @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to.
440
+ # @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to
422
441
  # @author.books # selects all books by using the Authorship join model
423
442
  #
424
443
  # You can also go through a +has_many+ association on the join model:
@@ -439,7 +458,7 @@ module ActiveRecord
439
458
  #
440
459
  # @firm = Firm.find :first
441
460
  # @firm.clients.collect { |c| c.invoices }.flatten # select all invoices for all clients of the firm
442
- # @firm.invoices # selects all invoices by going through the Client join model.
461
+ # @firm.invoices # selects all invoices by going through the Client join model
443
462
  #
444
463
  # Similarly you can go through a +has_one+ association on the join model:
445
464
  #
@@ -461,16 +480,18 @@ module ActiveRecord
461
480
  # @group.users.collect { |u| u.avatar }.flatten # select all avatars for all users in the group
462
481
  # @group.avatars # selects all avatars by going through the User join model.
463
482
  #
464
- # An important caveat with going through +has_one+ or +has_many+ associations on the join model is that these associations are
465
- # *read-only*. For example, the following would not work following the previous example:
483
+ # An important caveat with going through +has_one+ or +has_many+ associations on the
484
+ # join model is that these associations are *read-only*. For example, the following
485
+ # would not work following the previous example:
466
486
  #
467
- # @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around.
487
+ # @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around
468
488
  # @group.avatars.delete(@group.avatars.last) # so would this
469
489
  #
470
490
  # === Polymorphic Associations
471
491
  #
472
- # Polymorphic associations on models are not restricted on what types of models they can be associated with. Rather, they
473
- # specify an interface that a +has_many+ association must adhere to.
492
+ # Polymorphic associations on models are not restricted on what types of models they
493
+ # can be associated with. Rather, they specify an interface that a +has_many+ association
494
+ # must adhere to.
474
495
  #
475
496
  # class Asset < ActiveRecord::Base
476
497
  # belongs_to :attachable, :polymorphic => true
@@ -482,13 +503,16 @@ module ActiveRecord
482
503
  #
483
504
  # @asset.attachable = @post
484
505
  #
485
- # 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
486
- # an +attachable_id+ integer column and an +attachable_type+ string column.
506
+ # This works by using a type column in addition to a foreign key to specify the associated
507
+ # record. In the Asset example, you'd need an +attachable_id+ integer column and an
508
+ # +attachable_type+ string column.
487
509
  #
488
- # Using polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order
489
- # for the associations to work as expected, ensure that you store the base model for the STI models in the
490
- # type column of the polymorphic association. To continue with the asset example above, suppose there are guest posts
491
- # and member posts that use the posts table for STI. In this case, there must be a +type+ column in the posts table.
510
+ # Using polymorphic associations in combination with single table inheritance (STI) is
511
+ # a little tricky. In order for the associations to work as expected, ensure that you
512
+ # store the base model for the STI models in the type column of the polymorphic
513
+ # association. To continue with the asset example above, suppose there are guest posts
514
+ # and member posts that use the posts table for STI. In this case, there must be a +type+
515
+ # column in the posts table.
492
516
  #
493
517
  # class Asset < ActiveRecord::Base
494
518
  # belongs_to :attachable, :polymorphic => true
@@ -511,9 +535,10 @@ module ActiveRecord
511
535
  #
512
536
  # == Caching
513
537
  #
514
- # All of the methods are built on a simple caching principle that will keep the result of the last query around unless specifically
515
- # instructed not to. The cache is even shared across methods to make it even cheaper to use the macro-added methods without
516
- # worrying too much about performance at the first go. Example:
538
+ # All of the methods are built on a simple caching principle that will keep the result
539
+ # of the last query around unless specifically instructed not to. The cache is even
540
+ # shared across methods to make it even cheaper to use the macro-added methods without
541
+ # worrying too much about performance at the first go.
517
542
  #
518
543
  # project.milestones # fetches milestones from the database
519
544
  # project.milestones.size # uses the milestone cache
@@ -523,9 +548,10 @@ module ActiveRecord
523
548
  #
524
549
  # == Eager loading of associations
525
550
  #
526
- # Eager loading is a way to find objects of a certain class and a number of named associations. This is
527
- # 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
528
- # triggers 101 database queries. Through the use of eager loading, the 101 queries can be reduced to 2. Example:
551
+ # Eager loading is a way to find objects of a certain class and a number of named associations.
552
+ # This is one of the easiest ways of to prevent the dreaded 1+N problem in which fetching 100
553
+ # posts that each need to display their author triggers 101 database queries. Through the
554
+ # use of eager loading, the 101 queries can be reduced to 2.
529
555
  #
530
556
  # class Post < ActiveRecord::Base
531
557
  # belongs_to :author
@@ -540,44 +566,55 @@ module ActiveRecord
540
566
  # puts "Last comment on: " + post.comments.first.created_on
541
567
  # end
542
568
  #
543
- # To iterate over these one hundred posts, we'll generate 201 database queries. Let's first just optimize it for retrieving the author:
569
+ # To iterate over these one hundred posts, we'll generate 201 database queries. Let's
570
+ # first just optimize it for retrieving the author:
544
571
  #
545
572
  # for post in Post.find(:all, :include => :author)
546
573
  #
547
- # This references the name of the +belongs_to+ association that also used the <tt>:author</tt> symbol. After loading the posts, find
548
- # 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.
574
+ # This references the name of the +belongs_to+ association that also used the <tt>:author</tt>
575
+ # symbol. After loading the posts, find will collect the +author_id+ from each one and load
576
+ # all the referenced authors with one query. Doing so will cut down the number of queries
577
+ # from 201 to 102.
549
578
  #
550
579
  # We can improve upon the situation further by referencing both associations in the finder with:
551
580
  #
552
581
  # for post in Post.find(:all, :include => [ :author, :comments ])
553
582
  #
554
- # This will load all comments with a single query. This reduces the total number of queries to 3. More generally the number of queries
555
- # will be 1 plus the number of associations named (except if some of the associations are polymorphic +belongs_to+ - see below).
583
+ # This will load all comments with a single query. This reduces the total number of queries
584
+ # to 3. More generally the number of queries will be 1 plus the number of associations
585
+ # named (except if some of the associations are polymorphic +belongs_to+ - see below).
556
586
  #
557
587
  # To include a deep hierarchy of associations, use a hash:
558
588
  #
559
589
  # for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ])
560
590
  #
561
- # That'll grab not only all the comments but all their authors and gravatar pictures. You can mix and match
562
- # symbols, arrays and hashes in any combination to describe the associations you want to load.
591
+ # That'll grab not only all the comments but all their authors and gravatar pictures.
592
+ # You can mix and match symbols, arrays and hashes in any combination to describe the
593
+ # associations you want to load.
563
594
  #
564
- # 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
565
- # 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
566
- # 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.
595
+ # All of this power shouldn't fool you into thinking that you can pull out huge amounts
596
+ # of data with no performance penalty just because you've reduced the number of queries.
597
+ # The database still needs to send all the data to Active Record and it still needs to
598
+ # be processed. So it's no catch-all for performance problems, but it's a great way to
599
+ # cut down on the number of queries in a situation as the one described above.
567
600
  #
568
- # 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
569
- # Active Record falls back to the previously used LEFT OUTER JOIN based strategy. For example
601
+ # Since only one table is loaded at a time, conditions or orders cannot reference tables
602
+ # other than the main one. If this is the case Active Record falls back to the previously
603
+ # used LEFT OUTER JOIN based strategy. For example
570
604
  #
571
605
  # Post.find(:all, :include => [ :author, :comments ], :conditions => ['comments.approved = ?', true])
572
606
  #
573
- # 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
574
- # <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Note that using conditions like this can have unintended consequences.
575
- # 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
576
- # and not just to the association. You must disambiguate column references for this fallback to happen, for example
607
+ # This will result in a single SQL query with joins along the lines of:
608
+ # <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and
609
+ # <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Note that using conditions
610
+ # like this can have unintended consequences.
611
+ # In the above example posts with no approved comments are not returned at all, because
612
+ # the conditions apply to the SQL statement as a whole and not just to the association.
613
+ # You must disambiguate column references for this fallback to happen, for example
577
614
  # <tt>:order => "author.name DESC"</tt> will work but <tt>:order => "name DESC"</tt> will not.
578
615
  #
579
- # If you do want eager load only some members of an association it is usually more natural to <tt>:include</tt> an association
580
- # which has conditions defined on it:
616
+ # If you do want eager load only some members of an association it is usually more natural
617
+ # to <tt>:include</tt> an association which has conditions defined on it:
581
618
  #
582
619
  # class Post < ActiveRecord::Base
583
620
  # has_many :approved_comments, :class_name => 'Comment', :conditions => ['approved = ?', true]
@@ -585,9 +622,11 @@ module ActiveRecord
585
622
  #
586
623
  # Post.find(:all, :include => :approved_comments)
587
624
  #
588
- # This will load posts and eager load the +approved_comments+ association, which contains only those comments that have been approved.
625
+ # This will load posts and eager load the +approved_comments+ association, which contains
626
+ # only those comments that have been approved.
589
627
  #
590
- # If you eager load an association with a specified <tt>:limit</tt> option, it will be ignored, returning all the associated objects:
628
+ # If you eager load an association with a specified <tt>:limit</tt> option, it will be ignored,
629
+ # returning all the associated objects:
591
630
  #
592
631
  # class Picture < ActiveRecord::Base
593
632
  # has_many :most_recent_comments, :class_name => 'Comment', :order => 'id DESC', :limit => 10
@@ -595,8 +634,8 @@ module ActiveRecord
595
634
  #
596
635
  # Picture.find(:first, :include => :most_recent_comments).most_recent_comments # => returns all associated comments.
597
636
  #
598
- # When eager loaded, conditions are interpolated in the context of the model class, not the model instance. Conditions are lazily interpolated
599
- # before the actual model exists.
637
+ # When eager loaded, conditions are interpolated in the context of the model class, not
638
+ # the model instance. Conditions are lazily interpolated before the actual model exists.
600
639
  #
601
640
  # Eager loading is supported with polymorphic associations.
602
641
  #
@@ -608,17 +647,21 @@ module ActiveRecord
608
647
  #
609
648
  # Address.find(:all, :include => :addressable)
610
649
  #
611
- # This will execute one query to load the addresses and load the addressables with one query per addressable type.
612
- # 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
613
- # addressable types to load is determined on the back of the addresses loaded. This is not supported if Active Record has to fallback
614
- # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError. The reason is that the parent
615
- # model's type is a column value so its corresponding table name cannot be put in the +FROM+/+JOIN+ clauses of that query.
650
+ # This will execute one query to load the addresses and load the addressables with one
651
+ # query per addressable type.
652
+ # For example if all the addressables are either of class Person or Company then a total
653
+ # of 3 queries will be executed. The list of addressable types to load is determined on
654
+ # the back of the addresses loaded. This is not supported if Active Record has to fallback
655
+ # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
656
+ # The reason is that the parent model's type is a column value so its corresponding table
657
+ # name cannot be put in the +FROM+/+JOIN+ clauses of that query.
616
658
  #
617
659
  # == Table Aliasing
618
660
  #
619
- # 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,
620
- # the standard table name is used. The second time, the table is aliased as <tt>#{reflection_name}_#{parent_table_name}</tt>. Indexes are appended
621
- # for any more successive uses of the table name.
661
+ # Active Record uses table aliasing in the case that a table is referenced multiple times
662
+ # in a join. If a table is referenced only once, the standard table name is used. The
663
+ # second time, the table is aliased as <tt>#{reflection_name}_#{parent_table_name}</tt>.
664
+ # Indexes are appended for any more successive uses of the table name.
622
665
  #
623
666
  # Post.find :all, :joins => :comments
624
667
  # # => SELECT ... FROM posts INNER JOIN comments ON ...
@@ -651,7 +694,8 @@ module ActiveRecord
651
694
  # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
652
695
  # INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
653
696
  #
654
- # 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:
697
+ # If you wish to specify your own custom joins using a <tt>:joins</tt> option, those table
698
+ # names will take precedence over the eager associations:
655
699
  #
656
700
  # Post.find :all, :joins => :comments, :joins => "inner join comments ..."
657
701
  # # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
@@ -660,7 +704,8 @@ module ActiveRecord
660
704
  # INNER JOIN comments special_comments_posts ...
661
705
  # INNER JOIN comments ...
662
706
  #
663
- # Table aliases are automatically truncated according to the maximum length of table identifiers according to the specific database.
707
+ # Table aliases are automatically truncated according to the maximum length of table identifiers
708
+ # according to the specific database.
664
709
  #
665
710
  # == Modules
666
711
  #
@@ -676,9 +721,10 @@ module ActiveRecord
676
721
  # end
677
722
  # end
678
723
  #
679
- # When <tt>Firm#clients</tt> is called, it will in turn call <tt>MyApplication::Business::Client.find_all_by_firm_id(firm.id)</tt>.
680
- # If you want to associate with a class in another module scope, this can be done by specifying the complete class name.
681
- # Example:
724
+ # When <tt>Firm#clients</tt> is called, it will in turn call
725
+ # <tt>MyApplication::Business::Client.find_all_by_firm_id(firm.id)</tt>.
726
+ # If you want to associate with a class in another module scope, this can be done by
727
+ # specifying the complete class name.
682
728
  #
683
729
  # module MyApplication
684
730
  # module Business
@@ -694,8 +740,8 @@ module ActiveRecord
694
740
  #
695
741
  # == Bi-directional associations
696
742
  #
697
- # When you specify an association there is usually an association on the associated model that specifies the same
698
- # relationship in reverse. For example, with the following models:
743
+ # When you specify an association there is usually an association on the associated model
744
+ # that specifies the same relationship in reverse. For example, with the following models:
699
745
  #
700
746
  # class Dungeon < ActiveRecord::Base
701
747
  # has_many :traps
@@ -710,9 +756,11 @@ module ActiveRecord
710
756
  # belongs_to :dungeon
711
757
  # end
712
758
  #
713
- # The +traps+ association on +Dungeon+ and the the +dungeon+ association on +Trap+ are the inverse of each other and the
714
- # inverse of the +dungeon+ association on +EvilWizard+ is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
715
- # Active Record doesn't know anything about these inverse relationships and so no object loading optimisation is possible. For example:
759
+ # The +traps+ association on +Dungeon+ and the the +dungeon+ association on +Trap+ are
760
+ # the inverse of each other and the inverse of the +dungeon+ association on +EvilWizard+
761
+ # is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
762
+ # Active Record doesn't know anything about these inverse relationships and so no object
763
+ # loading optimisation is possible. For example:
716
764
  #
717
765
  # d = Dungeon.first
718
766
  # t = d.traps.first
@@ -720,9 +768,11 @@ module ActiveRecord
720
768
  # d.level = 10
721
769
  # d.level == t.dungeon.level # => false
722
770
  #
723
- # The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to the same object data from the database, but are
724
- # actually different in-memory copies of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell
725
- # Active Record about inverse relationships and it will optimise object loading. For example, if we changed our model definitions to:
771
+ # The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to
772
+ # the same object data from the database, but are actually different in-memory copies
773
+ # of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell
774
+ # Active Record about inverse relationships and it will optimise object loading. For
775
+ # example, if we changed our model definitions to:
726
776
  #
727
777
  # class Dungeon < ActiveRecord::Base
728
778
  # has_many :traps, :inverse_of => :dungeon
@@ -737,8 +787,8 @@ module ActiveRecord
737
787
  # belongs_to :dungeon, :inverse_of => :evil_wizard
738
788
  # end
739
789
  #
740
- # 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>
741
- # will return +true+.
790
+ # Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
791
+ # in-memory instance and our final <tt>d.level == t.dungeon.level</tt> will return +true+.
742
792
  #
743
793
  # There are limitations to <tt>:inverse_of</tt> support:
744
794
  #
@@ -748,13 +798,13 @@ module ActiveRecord
748
798
  #
749
799
  # == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt>
750
800
  #
751
- # If you attempt to assign an object to an association that doesn't match the inferred or specified <tt>:class_name</tt>, you'll
752
- # get an <tt>ActiveRecord::AssociationTypeMismatch</tt>.
801
+ # If you attempt to assign an object to an association that doesn't match the inferred
802
+ # or specified <tt>:class_name</tt>, you'll get an <tt>ActiveRecord::AssociationTypeMismatch</tt>.
753
803
  #
754
804
  # == Options
755
805
  #
756
- # All of the association macros can be specialized through options. This makes cases more complex than the simple and guessable ones
757
- # possible.
806
+ # All of the association macros can be specialized through options. This makes cases
807
+ # more complex than the simple and guessable ones possible.
758
808
  module ClassMethods
759
809
  # Specifies a one-to-many association. The following methods for retrieval and query of
760
810
  # collections of associated objects will be added:
@@ -764,7 +814,7 @@ module ActiveRecord
764
814
  # An empty array is returned if none are found.
765
815
  # [collection<<(object, ...)]
766
816
  # Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
767
- # Note that this operation instantly fires update sql without waiting for the save or update call on the
817
+ # Note that this operation instantly fires update sql without waiting for the save or update call on the
768
818
  # parent object.
769
819
  # [collection.delete(object, ...)]
770
820
  # Removes one or more objects from the collection by setting their foreign keys to +NULL+.
@@ -828,20 +878,22 @@ module ActiveRecord
828
878
  # === Supported options
829
879
  # [:class_name]
830
880
  # Specify the class name of the association. Use it only if that name can't be inferred
831
- # from the association name. So <tt>has_many :products</tt> will by default be linked to the Product class, but
832
- # if the real class name is SpecialProduct, you'll have to specify it with this option.
881
+ # from the association name. So <tt>has_many :products</tt> will by default be linked
882
+ # to the Product class, but if the real class name is SpecialProduct, you'll have to
883
+ # specify it with this option.
833
884
  # [:conditions]
834
885
  # Specify the conditions that the associated objects must meet in order to be included as a +WHERE+
835
- # SQL fragment, such as <tt>price > 5 AND name LIKE 'B%'</tt>. Record creations from the association are scoped if a hash
836
- # is used. <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt>
837
- # or <tt>@blog.posts.build</tt>.
886
+ # SQL fragment, such as <tt>price > 5 AND name LIKE 'B%'</tt>. Record creations from
887
+ # the association are scoped if a hash is used.
888
+ # <tt>has_many :posts, :conditions => {:published => true}</tt> will create published
889
+ # posts with <tt>@blog.posts.create</tt> or <tt>@blog.posts.build</tt>.
838
890
  # [:order]
839
891
  # Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
840
892
  # such as <tt>last_name, first_name DESC</tt>.
841
893
  # [:foreign_key]
842
894
  # Specify the foreign key used for the association. By default this is guessed to be the name
843
- # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+ association will use "person_id"
844
- # as the default <tt>:foreign_key</tt>.
895
+ # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+
896
+ # association will use "person_id" as the default <tt>:foreign_key</tt>.
845
897
  # [:primary_key]
846
898
  # Specify the method that returns the primary key used for the association. By default this is +id+.
847
899
  # [:dependent]
@@ -855,10 +907,12 @@ module ActiveRecord
855
907
  #
856
908
  # [:finder_sql]
857
909
  # Specify a complete SQL statement to fetch the association. This is a good way to go for complex
858
- # associations that depend on multiple tables. Note: When this option is used, +find_in_collection+ is _not_ added.
910
+ # associations that depend on multiple tables. Note: When this option is used, +find_in_collection+
911
+ # is _not_ added.
859
912
  # [:counter_sql]
860
913
  # Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
861
- # 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>.
914
+ # specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by
915
+ # replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
862
916
  # [:extend]
863
917
  # Specify a named module for extending the proxy. See "Association extensions".
864
918
  # [:include]
@@ -866,25 +920,31 @@ module ActiveRecord
866
920
  # [:group]
867
921
  # An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
868
922
  # [:having]
869
- # 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.
923
+ # Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt>
924
+ # returns. Uses the <tt>HAVING</tt> SQL-clause.
870
925
  # [:limit]
871
926
  # An integer determining the limit on the number of rows that should be returned.
872
927
  # [:offset]
873
- # An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows.
928
+ # An integer determining the offset from where the rows should be fetched. So at 5,
929
+ # it would skip the first 4 rows.
874
930
  # [:select]
875
- # 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
876
- # but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
931
+ # By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if
932
+ # you, for example, want to do a join but not include the joined columns. Do not forget
933
+ # to include the primary and foreign keys, otherwise it will raise an error.
877
934
  # [:as]
878
935
  # Specifies a polymorphic interface (See <tt>belongs_to</tt>).
879
936
  # [:through]
880
- # Specifies a join model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt>
881
- # are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a <tt>belongs_to</tt>
882
- # <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
883
- # API. For example, new join models are created for newly associated objects, and if some are gone their rows are deleted (directly,
937
+ # Specifies a join model through which to perform the query. Options for <tt>:class_name</tt>
938
+ # and <tt>:foreign_key</tt> are ignored, as the association uses the source reflection. You
939
+ # can only use a <tt>:through</tt> query through a <tt>belongs_to</tt>, <tt>has_one</tt>
940
+ # or <tt>has_many</tt> association on the join model. The collection of join models
941
+ # can be managed via the collection API. For example, new join models are created for
942
+ # newly associated objects, and if some are gone their rows are deleted (directly,
884
943
  # no destroy callbacks are triggered).
885
944
  # [:source]
886
- # Specifies the source association name used by <tt>has_many :through</tt> queries. Only use it if the name cannot be
887
- # inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either <tt>:subscribers</tt> or
945
+ # Specifies the source association name used by <tt>has_many :through</tt> queries.
946
+ # Only use it if the name cannot be inferred from the association.
947
+ # <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either <tt>:subscribers</tt> or
888
948
  # <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
889
949
  # [:source_type]
890
950
  # Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
@@ -894,14 +954,15 @@ module ActiveRecord
894
954
  # [:readonly]
895
955
  # If true, all the associated objects are readonly through the association.
896
956
  # [:validate]
897
- # If false, don't validate the associated objects when saving the parent object. true by default.
957
+ # If +false+, don't validate the associated objects when saving the parent object. true by default.
898
958
  # [:autosave]
899
- # If true, always save the associated objects or destroy them if marked for destruction, when saving the parent object.
900
- # If false, never save or destroy the associated objects.
959
+ # If true, always save the associated objects or destroy them if marked for destruction,
960
+ # when saving the parent object. If false, never save or destroy the associated objects.
901
961
  # By default, only save associated objects that are new records.
902
962
  # [:inverse_of]
903
- # Specifies the name of the <tt>belongs_to</tt> association on the associated object that is the inverse of this <tt>has_many</tt>
904
- # association. Does not work in combination with <tt>:through</tt> or <tt>:as</tt> options.
963
+ # Specifies the name of the <tt>belongs_to</tt> association on the associated object
964
+ # that is the inverse of this <tt>has_many</tt> association. Does not work in combination
965
+ # with <tt>:through</tt> or <tt>:as</tt> options.
905
966
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
906
967
  #
907
968
  # Option examples:
@@ -975,19 +1036,20 @@ module ActiveRecord
975
1036
  # [:conditions]
976
1037
  # Specify the conditions that the associated object must meet in order to be included as a +WHERE+
977
1038
  # SQL fragment, such as <tt>rank = 5</tt>. Record creation from the association is scoped if a hash
978
- # is used. <tt>has_one :account, :conditions => {:enabled => true}</tt> will create an enabled account with <tt>@company.create_account</tt>
979
- # or <tt>@company.build_account</tt>.
1039
+ # is used. <tt>has_one :account, :conditions => {:enabled => true}</tt> will create
1040
+ # an enabled account with <tt>@company.create_account</tt> or <tt>@company.build_account</tt>.
980
1041
  # [:order]
981
1042
  # Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
982
1043
  # such as <tt>last_name, first_name DESC</tt>.
983
1044
  # [:dependent]
984
1045
  # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
985
- # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to <tt>:nullify</tt>, the associated
986
- # object's foreign key is set to +NULL+. Also, association is assigned.
1046
+ # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
1047
+ # If set to <tt>:nullify</tt>, the associated object's foreign key is set to +NULL+.
1048
+ # Also, association is assigned.
987
1049
  # [:foreign_key]
988
1050
  # Specify the foreign key used for the association. By default this is guessed to be the name
989
- # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association will use "person_id"
990
- # as the default <tt>:foreign_key</tt>.
1051
+ # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association
1052
+ # will use "person_id" as the default <tt>:foreign_key</tt>.
991
1053
  # [:primary_key]
992
1054
  # Specify the method that returns the primary key used for the association. By default this is +id+.
993
1055
  # [:include]
@@ -995,15 +1057,18 @@ module ActiveRecord
995
1057
  # [:as]
996
1058
  # Specifies a polymorphic interface (See <tt>belongs_to</tt>).
997
1059
  # [:select]
998
- # 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
999
- # but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
1060
+ # By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example,
1061
+ # you want to do a join but not include the joined columns. Do not forget to include the
1062
+ # primary and foreign keys, otherwise it will raise an error.
1000
1063
  # [:through]
1001
- # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt>
1002
- # are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a
1003
- # <tt>has_one</tt> or <tt>belongs_to</tt> association on the join model.
1064
+ # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>
1065
+ # and <tt>:foreign_key</tt> are ignored, as the association uses the source reflection. You
1066
+ # can only use a <tt>:through</tt> query through a <tt>has_one</tt> or <tt>belongs_to</tt>
1067
+ # association on the join model.
1004
1068
  # [:source]
1005
- # Specifies the source association name used by <tt>has_one :through</tt> queries. Only use it if the name cannot be
1006
- # inferred from the association. <tt>has_one :favorite, :through => :favorites</tt> will look for a
1069
+ # Specifies the source association name used by <tt>has_one :through</tt> queries.
1070
+ # Only use it if the name cannot be inferred from the association.
1071
+ # <tt>has_one :favorite, :through => :favorites</tt> will look for a
1007
1072
  # <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
1008
1073
  # [:source_type]
1009
1074
  # Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
@@ -1011,19 +1076,21 @@ module ActiveRecord
1011
1076
  # [:readonly]
1012
1077
  # If true, the associated object is readonly through the association.
1013
1078
  # [:validate]
1014
- # If false, don't validate the associated object when saving the parent object. +false+ by default.
1079
+ # If +false+, don't validate the associated object when saving the parent object. +false+ by default.
1015
1080
  # [:autosave]
1016
- # If true, always save the associated object or destroy it if marked for destruction, when saving the parent object.
1017
- # If false, never save or destroy the associated object.
1081
+ # If true, always save the associated object or destroy it if marked for destruction,
1082
+ # when saving the parent object. If false, never save or destroy the associated object.
1018
1083
  # By default, only save the associated object if it's a new record.
1019
1084
  # [:inverse_of]
1020
- # Specifies the name of the <tt>belongs_to</tt> association on the associated object that is the inverse of this <tt>has_one</tt>
1021
- # association. Does not work in combination with <tt>:through</tt> or <tt>:as</tt> options.
1085
+ # Specifies the name of the <tt>belongs_to</tt> association on the associated object
1086
+ # that is the inverse of this <tt>has_one</tt> association. Does not work in combination
1087
+ # with <tt>:through</tt> or <tt>:as</tt> options.
1022
1088
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1023
1089
  #
1024
1090
  # Option examples:
1025
1091
  # has_one :credit_card, :dependent => :destroy # destroys the associated credit card
1026
- # has_one :credit_card, :dependent => :nullify # updates the associated records foreign key value to NULL rather than destroying it
1092
+ # has_one :credit_card, :dependent => :nullify # updates the associated records foreign
1093
+ # # key value to NULL rather than destroying it
1027
1094
  # has_one :last_comment, :class_name => "Comment", :order => "posted_on"
1028
1095
  # has_one :project_manager, :class_name => "Person", :conditions => "role = 'project_manager'"
1029
1096
  # has_one :attachment, :as => :attachable
@@ -1085,27 +1152,34 @@ module ActiveRecord
1085
1152
  # Specify the conditions that the associated object must meet in order to be included as a +WHERE+
1086
1153
  # SQL fragment, such as <tt>authorized = 1</tt>.
1087
1154
  # [:select]
1088
- # 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
1089
- # but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
1155
+ # By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed
1156
+ # if, for example, you want to do a join but not include the joined columns. Do not
1157
+ # forget to include the primary and foreign keys, otherwise it will raise an error.
1090
1158
  # [:foreign_key]
1091
1159
  # Specify the foreign key used for the association. By default this is guessed to be the name
1092
- # of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt> association will use
1093
- # "person_id" as the default <tt>:foreign_key</tt>. Similarly, <tt>belongs_to :favorite_person, :class_name => "Person"</tt>
1094
- # will use a foreign key of "favorite_person_id".
1160
+ # of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
1161
+ # association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
1162
+ # <tt>belongs_to :favorite_person, :class_name => "Person"</tt> will use a foreign key
1163
+ # of "favorite_person_id".
1095
1164
  # [:primary_key]
1096
- # Specify the method that returns the primary key of associated object used for the association. By default this is id.
1165
+ # Specify the method that returns the primary key of associated object used for the association.
1166
+ # By default this is id.
1097
1167
  # [:dependent]
1098
1168
  # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
1099
- # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. This option should not be specified when
1100
- # <tt>belongs_to</tt> is used in conjunction with a <tt>has_many</tt> relationship on another class because of the potential to leave
1169
+ # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
1170
+ # This option should not be specified when <tt>belongs_to</tt> is used in conjunction with
1171
+ # a <tt>has_many</tt> relationship on another class because of the potential to leave
1101
1172
  # orphaned records behind.
1102
1173
  # [:counter_cache]
1103
1174
  # Caches the number of belonging objects on the associate class through the use of +increment_counter+
1104
- # and +decrement_counter+. The counter cache is incremented when an object of this class is created and decremented when it's
1105
- # destroyed. This requires that a column named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
1106
- # is used on the associate class (such as a Post class). You can also specify a custom counter cache column by providing
1107
- # a column name instead of a +true+/+false+ value to this option (e.g., <tt>:counter_cache => :my_custom_counter</tt>.)
1108
- # Note: Specifying a counter cache will add it to that model's list of readonly attributes using +attr_readonly+.
1175
+ # and +decrement_counter+. The counter cache is incremented when an object of this
1176
+ # class is created and decremented when it's destroyed. This requires that a column
1177
+ # named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
1178
+ # is used on the associate class (such as a Post class). You can also specify a custom counter
1179
+ # cache column by providing a column name instead of a +true+/+false+ value to this
1180
+ # option (e.g., <tt>:counter_cache => :my_custom_counter</tt>.)
1181
+ # Note: Specifying a counter cache will add it to that model's list of readonly attributes
1182
+ # using +attr_readonly+.
1109
1183
  # [:include]
1110
1184
  # Specify second-order associations that should be eager loaded when this object is loaded.
1111
1185
  # [:polymorphic]
@@ -1115,17 +1189,20 @@ module ActiveRecord
1115
1189
  # [:readonly]
1116
1190
  # If true, the associated object is readonly through the association.
1117
1191
  # [:validate]
1118
- # If false, don't validate the associated objects when saving the parent object. +false+ by default.
1192
+ # If +false+, don't validate the associated objects when saving the parent object. +false+ by default.
1119
1193
  # [:autosave]
1120
- # If true, always save the associated object or destroy it if marked for destruction, when saving the parent object.
1194
+ # If true, always save the associated object or destroy it if marked for destruction, when
1195
+ # saving the parent object.
1121
1196
  # If false, never save or destroy the associated object.
1122
1197
  # By default, only save the associated object if it's a new record.
1123
1198
  # [:touch]
1124
- # If true, the associated object will be touched (the updated_at/on attributes set to now) when this record is either saved or
1125
- # destroyed. If you specify a symbol, that attribute will be updated with the current time instead of the updated_at/on attribute.
1199
+ # If true, the associated object will be touched (the updated_at/on attributes set to now)
1200
+ # when this record is either saved or destroyed. If you specify a symbol, that attribute
1201
+ # will be updated with the current time instead of the updated_at/on attribute.
1126
1202
  # [:inverse_of]
1127
- # 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>
1128
- # association. Does not work in combination with the <tt>:polymorphic</tt> options.
1203
+ # Specifies the name of the <tt>has_one</tt> or <tt>has_many</tt> association on the associated
1204
+ # object that is the inverse of this <tt>belongs_to</tt> association. Does not work in
1205
+ # combination with the <tt>:polymorphic</tt> options.
1129
1206
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1130
1207
  #
1131
1208
  # Option examples:
@@ -1159,9 +1236,10 @@ module ActiveRecord
1159
1236
  # Specifies a many-to-many relationship with another class. This associates two classes via an
1160
1237
  # intermediate join table. Unless the join table is explicitly specified as an option, it is
1161
1238
  # guessed using the lexical order of the class names. So a join between Developer and Project
1162
- # will give the default join table name of "developers_projects" because "D" outranks "P". Note that this precedence
1163
- # is calculated using the <tt><</tt> operator for String. This means that if the strings are of different lengths,
1164
- # and the strings are equal when compared up to the shortest length, then the longer string is considered of higher
1239
+ # will give the default join table name of "developers_projects" because "D" outranks "P".
1240
+ # Note that this precedence is calculated using the <tt><</tt> operator for String. This
1241
+ # means that if the strings are of different lengths, and the strings are equal when compared
1242
+ # up to the shortest length, then the longer string is considered of higher
1165
1243
  # lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers"
1166
1244
  # to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes",
1167
1245
  # 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
1183
1261
  # end
1184
1262
  # end
1185
1263
  #
1186
- # Deprecated: Any additional fields added to the join table will be placed as attributes when pulling records out through
1187
- # +has_and_belongs_to_many+ associations. Records returned from join tables with additional attributes will be marked as
1188
- # readonly (because we can't save changes to the additional attributes). It's strongly recommended that you upgrade any
1264
+ # Deprecated: Any additional fields added to the join table will be placed as attributes when
1265
+ # pulling records out through +has_and_belongs_to_many+ associations. Records returned from join
1266
+ # tables with additional attributes will be marked as readonly (because we can't save changes
1267
+ # to the additional attributes). It's strongly recommended that you upgrade any
1189
1268
  # associations with attributes to a real join model (see introduction).
1190
1269
  #
1191
1270
  # Adds the following methods for retrieval and query:
@@ -1196,7 +1275,7 @@ module ActiveRecord
1196
1275
  # [collection<<(object, ...)]
1197
1276
  # Adds one or more objects to the collection by creating associations in the join table
1198
1277
  # (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
1199
- # Note that this operation instantly fires update sql without waiting for the save or update call on the
1278
+ # Note that this operation instantly fires update sql without waiting for the save or update call on the
1200
1279
  # parent object.
1201
1280
  # [collection.delete(object, ...)]
1202
1281
  # Removes one or more objects from the collection by removing their associations from the join table.
@@ -1225,7 +1304,8 @@ module ActiveRecord
1225
1304
  # with +attributes+ and linked to this object through the join table, but has not yet been saved.
1226
1305
  # [collection.create(attributes = {})]
1227
1306
  # Returns a new object of the collection type that has been instantiated
1228
- # with +attributes+, linked to this object through the join table, and that has already been saved (if it passed the validation).
1307
+ # with +attributes+, linked to this object through the join table, and that has already been
1308
+ # saved (if it passed the validation).
1229
1309
  #
1230
1310
  # (+collection+ is replaced with the symbol passed as the first argument, so
1231
1311
  # <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.)
@@ -1260,8 +1340,9 @@ module ActiveRecord
1260
1340
  # MUST be declared underneath any +has_and_belongs_to_many+ declaration in order to work.
1261
1341
  # [:foreign_key]
1262
1342
  # Specify the foreign key used for the association. By default this is guessed to be the name
1263
- # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_and_belongs_to_many+ association
1264
- # to Project will use "person_id" as the default <tt>:foreign_key</tt>.
1343
+ # of this class in lower-case and "_id" suffixed. So a Person class that makes
1344
+ # a +has_and_belongs_to_many+ association to Project will use "person_id" as the
1345
+ # default <tt>:foreign_key</tt>.
1265
1346
  # [:association_foreign_key]
1266
1347
  # Specify the foreign key used for the association on the receiving side of the association.
1267
1348
  # 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
1269
1350
  # the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
1270
1351
  # [:conditions]
1271
1352
  # Specify the conditions that the associated object must meet in order to be included as a +WHERE+
1272
- # SQL fragment, such as <tt>authorized = 1</tt>. Record creations from the association are scoped if a hash is used.
1353
+ # SQL fragment, such as <tt>authorized = 1</tt>. Record creations from the association are
1354
+ # scoped if a hash is used.
1273
1355
  # <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt>
1274
1356
  # or <tt>@blog.posts.build</tt>.
1275
1357
  # [:order]
@@ -1281,7 +1363,8 @@ module ActiveRecord
1281
1363
  # Overwrite the default generated SQL statement used to fetch the association with a manual statement
1282
1364
  # [:counter_sql]
1283
1365
  # Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
1284
- # 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>.
1366
+ # specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by
1367
+ # replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
1285
1368
  # [:delete_sql]
1286
1369
  # Overwrite the default generated SQL statement used to remove links between the associated
1287
1370
  # classes with a manual statement.
@@ -1295,20 +1378,24 @@ module ActiveRecord
1295
1378
  # [:group]
1296
1379
  # An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
1297
1380
  # [:having]
1298
- # 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.
1381
+ # Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns.
1382
+ # Uses the <tt>HAVING</tt> SQL-clause.
1299
1383
  # [:limit]
1300
1384
  # An integer determining the limit on the number of rows that should be returned.
1301
1385
  # [:offset]
1302
- # An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows.
1386
+ # An integer determining the offset from where the rows should be fetched. So at 5,
1387
+ # it would skip the first 4 rows.
1303
1388
  # [:select]
1304
- # 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
1305
- # but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
1389
+ # By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example,
1390
+ # you want to do a join but not include the joined columns. Do not forget to include the primary
1391
+ # and foreign keys, otherwise it will raise an error.
1306
1392
  # [:readonly]
1307
1393
  # If true, all the associated objects are readonly through the association.
1308
1394
  # [:validate]
1309
- # If false, don't validate the associated objects when saving the parent object. +true+ by default.
1395
+ # If +false+, don't validate the associated objects when saving the parent object. +true+ by default.
1310
1396
  # [:autosave]
1311
- # If true, always save the associated objects or destroy them if marked for destruction, when saving the parent object.
1397
+ # If true, always save the associated objects or destroy them if marked for destruction, when
1398
+ # saving the parent object.
1312
1399
  # If false, never save or destroy the associated objects.
1313
1400
  # By default, only save associated objects that are new records.
1314
1401
  #
@@ -1376,7 +1463,7 @@ module ActiveRecord
1376
1463
  association = association_instance_get(reflection.name)
1377
1464
  association && association.loaded?
1378
1465
  end
1379
-
1466
+
1380
1467
  redefine_method("#{reflection.name}=") do |new_value|
1381
1468
  association = association_instance_get(reflection.name)
1382
1469
 
@@ -1387,7 +1474,7 @@ module ActiveRecord
1387
1474
  association.replace(new_value)
1388
1475
  association_instance_set(reflection.name, new_value.nil? ? nil : association)
1389
1476
  end
1390
-
1477
+
1391
1478
  redefine_method("set_#{reflection.name}_target") do |target|
1392
1479
  return if target.nil? and association_proxy_class == BelongsToAssociation
1393
1480
  association = association_proxy_class.new(self, reflection)
@@ -1410,17 +1497,17 @@ module ActiveRecord
1410
1497
 
1411
1498
  association
1412
1499
  end
1413
-
1500
+
1414
1501
  redefine_method("#{reflection.name.to_s.singularize}_ids") do
1415
1502
  if send(reflection.name).loaded? || reflection.options[:finder_sql]
1416
- send(reflection.name).map(&:id)
1503
+ send(reflection.name).map { |r| r.id }
1417
1504
  else
1418
1505
  if reflection.through_reflection && reflection.source_reflection.belongs_to?
1419
1506
  through = reflection.through_reflection
1420
1507
  primary_key = reflection.source_reflection.primary_key_name
1421
- send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map!(&:"#{primary_key}")
1508
+ send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map! { |r| r.send(primary_key) }
1422
1509
  else
1423
- send(reflection.name).select("#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").except(:includes).map!(&:id)
1510
+ send(reflection.name).select("#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").except(:includes).map! { |r| r.id }
1424
1511
  end
1425
1512
  end
1426
1513
  end
@@ -1437,10 +1524,12 @@ module ActiveRecord
1437
1524
  association.replace(new_value)
1438
1525
  association
1439
1526
  end
1440
-
1527
+
1441
1528
  redefine_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
1442
- ids = (new_value || []).reject { |nid| nid.blank? }.map(&:to_i)
1443
- send("#{reflection.name}=", reflection.klass.find(ids).index_by(&:id).values_at(*ids))
1529
+ pk_column = reflection.primary_key_column
1530
+ ids = (new_value || []).reject { |nid| nid.blank? }
1531
+ ids.map!{ |i| pk_column.type_cast(i) }
1532
+ send("#{reflection.name}=", reflection.klass.find(ids).index_by{ |r| r.id }.values_at(*ids))
1444
1533
  end
1445
1534
  end
1446
1535
  end
@@ -1498,6 +1587,7 @@ module ActiveRecord
1498
1587
  end
1499
1588
  end
1500
1589
  after_save(method_name)
1590
+ after_touch(method_name)
1501
1591
  after_destroy(method_name)
1502
1592
  end
1503
1593
 
@@ -1802,9 +1892,7 @@ module ActiveRecord
1802
1892
  case associations
1803
1893
  when Symbol, String
1804
1894
  reflection = base.reflections[associations]
1805
- if reflection && reflection.collection?
1806
- records.each { |record| record.send(reflection.name).target.uniq! }
1807
- end
1895
+ remove_uniq_by_reflection(reflection, records)
1808
1896
  when Array
1809
1897
  associations.each do |association|
1810
1898
  remove_duplicate_results!(base, records, association)
@@ -1812,6 +1900,7 @@ module ActiveRecord
1812
1900
  when Hash
1813
1901
  associations.keys.each do |name|
1814
1902
  reflection = base.reflections[name]
1903
+ remove_uniq_by_reflection(reflection, records)
1815
1904
 
1816
1905
  parent_records = []
1817
1906
  records.each do |record|
@@ -1830,6 +1919,7 @@ module ActiveRecord
1830
1919
  end
1831
1920
 
1832
1921
  protected
1922
+
1833
1923
  def build(associations, parent = nil, join_class = Arel::InnerJoin)
1834
1924
  parent ||= @joins.last
1835
1925
  case associations
@@ -1852,6 +1942,12 @@ module ActiveRecord
1852
1942
  end
1853
1943
  end
1854
1944
 
1945
+ def remove_uniq_by_reflection(reflection, records)
1946
+ if reflection && reflection.collection?
1947
+ records.each { |record| record.send(reflection.name).target.uniq! }
1948
+ end
1949
+ end
1950
+
1855
1951
  def build_join_association(reflection, parent)
1856
1952
  JoinAssociation.new(reflection, self, parent)
1857
1953
  end