activerecord 4.2.11.3 → 5.0.0.beta1

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 (229) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1029 -1349
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -7
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record.rb +7 -3
  7. data/lib/active_record/aggregations.rb +35 -25
  8. data/lib/active_record/association_relation.rb +2 -2
  9. data/lib/active_record/associations.rb +305 -204
  10. data/lib/active_record/associations/alias_tracker.rb +19 -16
  11. data/lib/active_record/associations/association.rb +10 -8
  12. data/lib/active_record/associations/association_scope.rb +73 -102
  13. data/lib/active_record/associations/belongs_to_association.rb +20 -32
  14. data/lib/active_record/associations/builder/association.rb +28 -34
  15. data/lib/active_record/associations/builder/belongs_to.rb +41 -18
  16. data/lib/active_record/associations/builder/collection_association.rb +8 -24
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +11 -11
  18. data/lib/active_record/associations/builder/has_many.rb +4 -4
  19. data/lib/active_record/associations/builder/has_one.rb +10 -5
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -9
  21. data/lib/active_record/associations/collection_association.rb +40 -43
  22. data/lib/active_record/associations/collection_proxy.rb +55 -29
  23. data/lib/active_record/associations/foreign_association.rb +1 -1
  24. data/lib/active_record/associations/has_many_association.rb +20 -71
  25. data/lib/active_record/associations/has_many_through_association.rb +8 -52
  26. data/lib/active_record/associations/has_one_association.rb +12 -5
  27. data/lib/active_record/associations/join_dependency.rb +28 -18
  28. data/lib/active_record/associations/join_dependency/join_association.rb +13 -12
  29. data/lib/active_record/associations/preloader.rb +13 -4
  30. data/lib/active_record/associations/preloader/association.rb +45 -51
  31. data/lib/active_record/associations/preloader/collection_association.rb +0 -6
  32. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  33. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +5 -4
  35. data/lib/active_record/associations/singular_association.rb +6 -0
  36. data/lib/active_record/associations/through_association.rb +11 -3
  37. data/lib/active_record/attribute.rb +61 -17
  38. data/lib/active_record/attribute/user_provided_default.rb +23 -0
  39. data/lib/active_record/attribute_assignment.rb +27 -140
  40. data/lib/active_record/attribute_decorators.rb +6 -5
  41. data/lib/active_record/attribute_methods.rb +79 -26
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
  43. data/lib/active_record/attribute_methods/dirty.rb +46 -86
  44. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  45. data/lib/active_record/attribute_methods/query.rb +2 -2
  46. data/lib/active_record/attribute_methods/read.rb +26 -42
  47. data/lib/active_record/attribute_methods/serialization.rb +13 -16
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +42 -9
  49. data/lib/active_record/attribute_methods/write.rb +13 -24
  50. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  51. data/lib/active_record/attribute_set.rb +30 -3
  52. data/lib/active_record/attribute_set/builder.rb +6 -4
  53. data/lib/active_record/attributes.rb +194 -81
  54. data/lib/active_record/autosave_association.rb +33 -15
  55. data/lib/active_record/base.rb +30 -18
  56. data/lib/active_record/callbacks.rb +36 -40
  57. data/lib/active_record/coders/yaml_column.rb +20 -8
  58. data/lib/active_record/collection_cache_key.rb +31 -0
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +431 -122
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +40 -22
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -8
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +46 -38
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +229 -185
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +52 -13
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +275 -115
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +32 -33
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -32
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +384 -221
  70. data/lib/active_record/connection_adapters/column.rb +27 -41
  71. data/lib/active_record/connection_adapters/connection_specification.rb +2 -21
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  73. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +57 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +69 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +59 -0
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +22 -101
  77. data/lib/active_record/connection_adapters/postgresql/column.rb +6 -10
  78. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +3 -3
  79. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
  80. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +23 -57
  81. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
  85. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
  87. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +23 -16
  92. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
  96. data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -11
  97. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +54 -0
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +174 -128
  101. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  102. data/lib/active_record/connection_adapters/postgresql_adapter.rb +184 -112
  103. data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
  104. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  105. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +15 -0
  106. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +134 -110
  107. data/lib/active_record/connection_adapters/statement_pool.rb +28 -11
  108. data/lib/active_record/connection_handling.rb +5 -5
  109. data/lib/active_record/core.rb +72 -104
  110. data/lib/active_record/counter_cache.rb +9 -20
  111. data/lib/active_record/dynamic_matchers.rb +1 -20
  112. data/lib/active_record/enum.rb +110 -76
  113. data/lib/active_record/errors.rb +72 -47
  114. data/lib/active_record/explain_registry.rb +1 -1
  115. data/lib/active_record/explain_subscriber.rb +1 -1
  116. data/lib/active_record/fixture_set/file.rb +19 -4
  117. data/lib/active_record/fixtures.rb +76 -40
  118. data/lib/active_record/gem_version.rb +4 -4
  119. data/lib/active_record/inheritance.rb +27 -40
  120. data/lib/active_record/integration.rb +4 -4
  121. data/lib/active_record/legacy_yaml_adapter.rb +18 -2
  122. data/lib/active_record/locale/en.yml +3 -2
  123. data/lib/active_record/locking/optimistic.rb +10 -14
  124. data/lib/active_record/locking/pessimistic.rb +1 -1
  125. data/lib/active_record/log_subscriber.rb +40 -22
  126. data/lib/active_record/migration.rb +304 -133
  127. data/lib/active_record/migration/command_recorder.rb +59 -18
  128. data/lib/active_record/migration/compatibility.rb +90 -0
  129. data/lib/active_record/model_schema.rb +92 -40
  130. data/lib/active_record/nested_attributes.rb +45 -34
  131. data/lib/active_record/null_relation.rb +15 -7
  132. data/lib/active_record/persistence.rb +112 -72
  133. data/lib/active_record/querying.rb +6 -5
  134. data/lib/active_record/railtie.rb +20 -13
  135. data/lib/active_record/railties/controller_runtime.rb +1 -1
  136. data/lib/active_record/railties/databases.rake +47 -38
  137. data/lib/active_record/readonly_attributes.rb +1 -1
  138. data/lib/active_record/reflection.rb +182 -57
  139. data/lib/active_record/relation.rb +152 -100
  140. data/lib/active_record/relation/batches.rb +133 -33
  141. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  142. data/lib/active_record/relation/calculations.rb +80 -101
  143. data/lib/active_record/relation/delegation.rb +6 -19
  144. data/lib/active_record/relation/finder_methods.rb +58 -46
  145. data/lib/active_record/relation/from_clause.rb +32 -0
  146. data/lib/active_record/relation/merger.rb +13 -42
  147. data/lib/active_record/relation/predicate_builder.rb +99 -105
  148. data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
  149. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +78 -0
  150. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  151. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  152. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  153. data/lib/active_record/relation/predicate_builder/range_handler.rb +17 -0
  154. data/lib/active_record/relation/query_attribute.rb +19 -0
  155. data/lib/active_record/relation/query_methods.rb +274 -238
  156. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  157. data/lib/active_record/relation/spawn_methods.rb +3 -6
  158. data/lib/active_record/relation/where_clause.rb +173 -0
  159. data/lib/active_record/relation/where_clause_factory.rb +37 -0
  160. data/lib/active_record/result.rb +4 -3
  161. data/lib/active_record/runtime_registry.rb +1 -1
  162. data/lib/active_record/sanitization.rb +94 -65
  163. data/lib/active_record/schema.rb +23 -22
  164. data/lib/active_record/schema_dumper.rb +33 -22
  165. data/lib/active_record/schema_migration.rb +10 -4
  166. data/lib/active_record/scoping.rb +17 -6
  167. data/lib/active_record/scoping/default.rb +19 -6
  168. data/lib/active_record/scoping/named.rb +39 -28
  169. data/lib/active_record/secure_token.rb +38 -0
  170. data/lib/active_record/serialization.rb +2 -4
  171. data/lib/active_record/statement_cache.rb +15 -13
  172. data/lib/active_record/store.rb +8 -3
  173. data/lib/active_record/suppressor.rb +54 -0
  174. data/lib/active_record/table_metadata.rb +64 -0
  175. data/lib/active_record/tasks/database_tasks.rb +30 -40
  176. data/lib/active_record/tasks/mysql_database_tasks.rb +7 -15
  177. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -2
  178. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  179. data/lib/active_record/timestamp.rb +16 -9
  180. data/lib/active_record/touch_later.rb +58 -0
  181. data/lib/active_record/transactions.rb +138 -56
  182. data/lib/active_record/type.rb +66 -17
  183. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  184. data/lib/active_record/type/date.rb +2 -45
  185. data/lib/active_record/type/date_time.rb +2 -49
  186. data/lib/active_record/type/internal/abstract_json.rb +33 -0
  187. data/lib/active_record/type/internal/timezone.rb +15 -0
  188. data/lib/active_record/type/serialized.rb +9 -14
  189. data/lib/active_record/type/time.rb +3 -21
  190. data/lib/active_record/type/type_map.rb +4 -4
  191. data/lib/active_record/type_caster.rb +7 -0
  192. data/lib/active_record/type_caster/connection.rb +29 -0
  193. data/lib/active_record/type_caster/map.rb +19 -0
  194. data/lib/active_record/validations.rb +33 -32
  195. data/lib/active_record/validations/absence.rb +24 -0
  196. data/lib/active_record/validations/associated.rb +10 -3
  197. data/lib/active_record/validations/length.rb +36 -0
  198. data/lib/active_record/validations/presence.rb +12 -12
  199. data/lib/active_record/validations/uniqueness.rb +24 -21
  200. data/lib/rails/generators/active_record/migration.rb +7 -0
  201. data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
  202. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
  203. data/lib/rails/generators/active_record/migration/templates/migration.rb +4 -1
  204. data/lib/rails/generators/active_record/model/model_generator.rb +21 -15
  205. data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
  206. metadata +50 -35
  207. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  208. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  209. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
  210. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  211. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  212. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  213. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  214. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  215. data/lib/active_record/type/big_integer.rb +0 -13
  216. data/lib/active_record/type/binary.rb +0 -50
  217. data/lib/active_record/type/boolean.rb +0 -31
  218. data/lib/active_record/type/decimal.rb +0 -64
  219. data/lib/active_record/type/decimal_without_scale.rb +0 -11
  220. data/lib/active_record/type/decorator.rb +0 -14
  221. data/lib/active_record/type/float.rb +0 -19
  222. data/lib/active_record/type/integer.rb +0 -59
  223. data/lib/active_record/type/mutable.rb +0 -16
  224. data/lib/active_record/type/numeric.rb +0 -36
  225. data/lib/active_record/type/string.rb +0 -40
  226. data/lib/active_record/type/text.rb +0 -11
  227. data/lib/active_record/type/time_value.rb +0 -38
  228. data/lib/active_record/type/unsigned_integer.rb +0 -15
  229. data/lib/active_record/type/value.rb +0 -110
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2014 David Heinemeier Hansson
1
+ Copyright (c) 2004-2015 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -26,13 +26,13 @@ The Product class is automatically mapped to the table named "products",
26
26
  which might look like this:
27
27
 
28
28
  CREATE TABLE products (
29
- id int(11) NOT NULL auto_increment,
29
+ id int NOT NULL auto_increment,
30
30
  name varchar(255),
31
31
  PRIMARY KEY (id)
32
32
  );
33
33
 
34
- This would also define the following accessors: `Product#name` and
35
- `Product#name=(new_name)`.
34
+ This would also define the following accessors: <tt>Product#name</tt> and
35
+ <tt>Product#name=(new_name)</tt>.
36
36
 
37
37
 
38
38
  * Associations between objects defined by simple class methods.
@@ -138,7 +138,7 @@ This would also define the following accessors: `Product#name` and
138
138
 
139
139
  * Database agnostic schema management with Migrations.
140
140
 
141
- class AddSystemSettings < ActiveRecord::Migration
141
+ class AddSystemSettings < ActiveRecord::Migration[5.0]
142
142
  def up
143
143
  create_table :system_settings do |t|
144
144
  t.string :name
@@ -188,11 +188,11 @@ Admit the Database:
188
188
 
189
189
  The latest version of Active Record can be installed with RubyGems:
190
190
 
191
- % [sudo] gem install activerecord
191
+ $ gem install activerecord
192
192
 
193
193
  Source code can be downloaded as part of the Rails project on GitHub:
194
194
 
195
- * https://github.com/rails/rails/tree/4-2-stable/activerecord
195
+ * https://github.com/rails/rails/tree/master/activerecord
196
196
 
197
197
 
198
198
  == License
@@ -215,4 +215,3 @@ Bug reports can be filed for the Ruby on Rails project here:
215
215
  Feature requests should be discussed on the rails-core mailing list here:
216
216
 
217
217
  * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
218
-
@@ -39,8 +39,8 @@ class Exhibit < ActiveRecord::Base
39
39
  where("notes IS NOT NULL")
40
40
  end
41
41
 
42
- def self.look(exhibits) exhibits.each { |e| e.look } end
43
- def self.feel(exhibits) exhibits.each { |e| e.feel } end
42
+ def self.look(exhibits) exhibits.each(&:look) end
43
+ def self.feel(exhibits) exhibits.each(&:feel) end
44
44
  end
45
45
 
46
46
  def progress_bar(int); print "." if (int%100).zero? ; end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2004-2014 David Heinemeier Hansson
2
+ # Copyright (c) 2004-2015 David Heinemeier Hansson
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -43,14 +43,17 @@ module ActiveRecord
43
43
  autoload :Explain
44
44
  autoload :Inheritance
45
45
  autoload :Integration
46
+ autoload :LegacyYamlAdapter
46
47
  autoload :Migration
47
48
  autoload :Migrator, 'active_record/migration'
48
49
  autoload :ModelSchema
49
50
  autoload :NestedAttributes
50
51
  autoload :NoTouching
52
+ autoload :TouchLater
51
53
  autoload :Persistence
52
54
  autoload :QueryCache
53
55
  autoload :Querying
56
+ autoload :CollectionCacheKey
54
57
  autoload :ReadonlyAttributes
55
58
  autoload :RecordInvalid, 'active_record/validations'
56
59
  autoload :Reflection
@@ -63,10 +66,13 @@ module ActiveRecord
63
66
  autoload :Serialization
64
67
  autoload :StatementCache
65
68
  autoload :Store
69
+ autoload :Suppressor
70
+ autoload :TableMetadata
66
71
  autoload :Timestamp
67
72
  autoload :Transactions
68
73
  autoload :Translation
69
74
  autoload :Validations
75
+ autoload :SecureToken
70
76
 
71
77
  eager_autoload do
72
78
  autoload :ActiveRecordError, 'active_record/errors'
@@ -79,8 +85,6 @@ module ActiveRecord
79
85
  autoload :AttributeMethods
80
86
  autoload :AutosaveAssociation
81
87
 
82
- autoload :LegacyYamlAdapter
83
-
84
88
  autoload :Relation
85
89
  autoload :AssociationRelation
86
90
  autoload :NullRelation
@@ -1,14 +1,31 @@
1
1
  module ActiveRecord
2
- # = Active Record Aggregations
3
- module Aggregations # :nodoc:
2
+ # See ActiveRecord::Aggregations::ClassMethods for documentation
3
+ module Aggregations
4
4
  extend ActiveSupport::Concern
5
5
 
6
- def clear_aggregation_cache #:nodoc:
7
- @aggregation_cache.clear if persisted?
6
+ def initialize_dup(*) # :nodoc:
7
+ @aggregation_cache = {}
8
+ super
8
9
  end
9
10
 
10
- # Active Record implements aggregation through a macro-like class method called +composed_of+
11
- # for representing attributes as value objects. It expresses relationships like "Account [is]
11
+ def reload(*) # :nodoc:
12
+ clear_aggregation_cache
13
+ super
14
+ end
15
+
16
+ private
17
+
18
+ def clear_aggregation_cache # :nodoc:
19
+ @aggregation_cache.clear if persisted?
20
+ end
21
+
22
+ def init_internals # :nodoc:
23
+ @aggregation_cache = {}
24
+ super
25
+ end
26
+
27
+ # Active Record implements aggregation through a macro-like class method called #composed_of
28
+ # for representing attributes as value objects. It expresses relationships like "Account [is]
12
29
  # composed of Money [among other things]" or "Person [is] composed of [an] address". Each call
13
30
  # to the macro adds a description of how the value objects are created from the attributes of
14
31
  # the entity object (when the entity is initialized either as a new object or from finding an
@@ -87,11 +104,6 @@ module ActiveRecord
87
104
  # customer.address_city = "Copenhagen"
88
105
  # customer.address # => Address.new("Hyancintvej", "Copenhagen")
89
106
  #
90
- # customer.address_street = "Vesterbrogade"
91
- # customer.address # => Address.new("Hyancintvej", "Copenhagen")
92
- # customer.clear_aggregation_cache
93
- # customer.address # => Address.new("Vesterbrogade", "Copenhagen")
94
- #
95
107
  # customer.address = Address.new("May Street", "Chicago")
96
108
  # customer.address_street # => "May Street"
97
109
  # customer.address_city # => "Chicago"
@@ -108,12 +120,12 @@ module ActiveRecord
108
120
  #
109
121
  # It's also important to treat the value objects as immutable. Don't allow the Money object to have
110
122
  # its amount changed after creation. Create a new Money object with the new value instead. The
111
- # Money#exchange_to method is an example of this. It returns a new value object instead of changing
123
+ # <tt>Money#exchange_to</tt> method is an example of this. It returns a new value object instead of changing
112
124
  # its own values. Active Record won't persist value objects that have been changed through means
113
125
  # other than the writer method.
114
126
  #
115
127
  # The immutable requirement is enforced by Active Record by freezing any object assigned as a value
116
- # object. Attempting to change it afterwards will result in a RuntimeError.
128
+ # object. Attempting to change it afterwards will result in a +RuntimeError+.
117
129
  #
118
130
  # Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not
119
131
  # keeping value objects immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable
@@ -122,17 +134,17 @@ module ActiveRecord
122
134
  #
123
135
  # By default value objects are initialized by calling the <tt>new</tt> constructor of the value
124
136
  # class passing each of the mapped attributes, in the order specified by the <tt>:mapping</tt>
125
- # option, as arguments. If the value class doesn't support this convention then +composed_of+ allows
137
+ # option, as arguments. If the value class doesn't support this convention then #composed_of allows
126
138
  # a custom constructor to be specified.
127
139
  #
128
140
  # When a new value is assigned to the value object, the default assumption is that the new value
129
141
  # is an instance of the value class. Specifying a custom converter allows the new value to be automatically
130
142
  # converted to an instance of value class if necessary.
131
143
  #
132
- # For example, the NetworkResource model has +network_address+ and +cidr_range+ attributes that should be
133
- # aggregated using the NetAddr::CIDR value class (http://www.ruby-doc.org/gems/docs/n/netaddr-1.5.0/NetAddr/CIDR.html).
144
+ # For example, the +NetworkResource+ model has +network_address+ and +cidr_range+ attributes that should be
145
+ # aggregated using the +NetAddr::CIDR+ value class (http://www.rubydoc.info/gems/netaddr/1.5.0/NetAddr/CIDR).
134
146
  # The constructor for the value class is called +create+ and it expects a CIDR address string as a parameter.
135
- # New values can be assigned to the value object using either another NetAddr::CIDR object, a string
147
+ # New values can be assigned to the value object using either another +NetAddr::CIDR+ object, a string
136
148
  # or an array. The <tt>:constructor</tt> and <tt>:converter</tt> options can be used to meet
137
149
  # these requirements:
138
150
  #
@@ -161,7 +173,7 @@ module ActiveRecord
161
173
  #
162
174
  # == Finding records by a value object
163
175
  #
164
- # Once a +composed_of+ relationship is specified for a model, records can be loaded from the database
176
+ # Once a #composed_of relationship is specified for a model, records can be loaded from the database
165
177
  # by specifying an instance of the value object in the conditions hash. The following example
166
178
  # finds all customers with +balance_amount+ equal to 20 and +balance_currency+ equal to "USD":
167
179
  #
@@ -174,7 +186,7 @@ module ActiveRecord
174
186
  # Options are:
175
187
  # * <tt>:class_name</tt> - Specifies the class name of the association. Use it only if that name
176
188
  # can't be inferred from the part id. So <tt>composed_of :address</tt> will by default be linked
177
- # to the Address class, but if the real class name is CompanyAddress, you'll have to specify it
189
+ # to the Address class, but if the real class name is +CompanyAddress+, you'll have to specify it
178
190
  # with this option.
179
191
  # * <tt>:mapping</tt> - Specifies the mapping of entity attributes to attributes of the value
180
192
  # object. Each mapping is represented as an array where the first item is the name of the
@@ -244,17 +256,15 @@ module ActiveRecord
244
256
  def writer_method(name, class_name, mapping, allow_nil, converter)
245
257
  define_method("#{name}=") do |part|
246
258
  klass = class_name.constantize
259
+ if part.is_a?(Hash)
260
+ raise ArgumentError unless part.size == part.keys.max
261
+ part = klass.new(*part.sort.map(&:last))
262
+ end
247
263
 
248
264
  unless part.is_a?(klass) || converter.nil? || part.nil?
249
265
  part = converter.respond_to?(:call) ? converter.call(part) : klass.send(converter, part)
250
266
  end
251
267
 
252
- hash_from_multiparameter_assignment = part.is_a?(Hash) &&
253
- part.each_key.all? { |k| k.is_a?(Integer) }
254
- if hash_from_multiparameter_assignment
255
- part = klass.new(*part.values)
256
- end
257
-
258
268
  if part.nil? && allow_nil
259
269
  mapping.each { |key, _| self[key] = nil }
260
270
  @aggregation_cache[name] = nil
@@ -1,7 +1,7 @@
1
1
  module ActiveRecord
2
2
  class AssociationRelation < Relation
3
- def initialize(klass, table, association)
4
- super(klass, table)
3
+ def initialize(klass, table, predicate_builder, association)
4
+ super(klass, table, predicate_builder)
5
5
  @association = association
6
6
  end
7
7
 
@@ -5,95 +5,170 @@ require 'active_record/errors'
5
5
 
6
6
  module ActiveRecord
7
7
  class AssociationNotFoundError < ConfigurationError #:nodoc:
8
- def initialize(record, association_name)
9
- super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
8
+ def initialize(record = nil, association_name = nil)
9
+ if record && association_name
10
+ super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
11
+ else
12
+ super("Association was not found.")
13
+ end
10
14
  end
11
15
  end
12
16
 
13
17
  class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
14
- def initialize(reflection, associated_class = nil)
15
- super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
18
+ def initialize(reflection = nil, associated_class = nil)
19
+ if reflection
20
+ super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
21
+ else
22
+ super("Could not find the inverse association.")
23
+ end
16
24
  end
17
25
  end
18
26
 
19
27
  class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc:
20
- def initialize(owner_class_name, reflection)
21
- super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class_name}")
28
+ def initialize(owner_class_name = nil, reflection = nil)
29
+ if owner_class_name && reflection
30
+ super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class_name}")
31
+ else
32
+ super("Could not find the association.")
33
+ end
22
34
  end
23
35
  end
24
36
 
25
37
  class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc:
26
- def initialize(owner_class_name, reflection, source_reflection)
27
- super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
38
+ def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
39
+ if owner_class_name && reflection && source_reflection
40
+ super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
41
+ else
42
+ super("Cannot have a has_many :through association.")
43
+ end
28
44
  end
29
45
  end
30
46
 
31
47
  class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
32
- def initialize(owner_class_name, reflection)
33
- super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
48
+ def initialize(owner_class_name = nil, reflection = nil)
49
+ if owner_class_name && reflection
50
+ super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
51
+ else
52
+ super("Cannot have a has_many :through association.")
53
+ end
34
54
  end
35
55
  end
36
56
 
37
57
  class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc:
38
- def initialize(owner_class_name, reflection, source_reflection)
39
- super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
58
+ def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
59
+ if owner_class_name && reflection && source_reflection
60
+ super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
61
+ else
62
+ super("Cannot have a has_many :through association.")
63
+ end
40
64
  end
41
65
  end
42
66
 
43
67
  class HasOneThroughCantAssociateThroughCollection < ActiveRecordError #:nodoc:
44
- def initialize(owner_class_name, reflection, through_reflection)
45
- super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
68
+ def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
69
+ if owner_class_name && reflection && through_reflection
70
+ super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
71
+ else
72
+ super("Cannot have a has_one :through association.")
73
+ end
46
74
  end
47
75
  end
48
76
 
49
77
  class HasOneAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
50
- def initialize(owner_class_name, reflection)
51
- super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
78
+ def initialize(owner_class_name = nil, reflection = nil)
79
+ if owner_class_name && reflection
80
+ super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
81
+ else
82
+ super("Cannot have a has_one :through association.")
83
+ end
52
84
  end
53
85
  end
54
86
 
55
87
  class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
56
- def initialize(reflection)
57
- through_reflection = reflection.through_reflection
58
- source_reflection_names = reflection.source_reflection_names
59
- source_associations = reflection.through_reflection.klass._reflections.keys
60
- 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)}?")
88
+ def initialize(reflection = nil)
89
+ if reflection
90
+ through_reflection = reflection.through_reflection
91
+ source_reflection_names = reflection.source_reflection_names
92
+ source_associations = reflection.through_reflection.klass._reflections.keys
93
+ 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)}?")
94
+ else
95
+ super("Could not find the source association(s).")
96
+ end
61
97
  end
62
98
  end
63
99
 
64
- class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
65
- def initialize(owner, reflection)
66
- super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
100
+ class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
101
+ def initialize(owner = nil, reflection = nil)
102
+ if owner && reflection
103
+ super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
104
+ else
105
+ super("Cannot modify association.")
106
+ end
67
107
  end
68
108
  end
69
109
 
110
+ class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
111
+ end
112
+
113
+ class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
114
+ end
115
+
70
116
  class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc:
71
- def initialize(owner, reflection)
72
- super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.")
117
+ def initialize(owner = nil, reflection = nil)
118
+ if owner && reflection
119
+ super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.")
120
+ else
121
+ super("Cannot associate new records.")
122
+ end
73
123
  end
74
124
  end
75
125
 
76
126
  class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc:
77
- def initialize(owner, reflection)
78
- super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.")
127
+ def initialize(owner = nil, reflection = nil)
128
+ if owner && reflection
129
+ super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.")
130
+ else
131
+ super("Cannot dissociate new records.")
132
+ end
79
133
  end
80
134
  end
81
135
 
82
- class HasManyThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
83
- def initialize(owner, reflection)
84
- super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
136
+ class ThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
137
+ def initialize(owner = nil, reflection = nil)
138
+ if owner && reflection
139
+ super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
140
+ else
141
+ super("Through nested associations are read-only.")
142
+ end
85
143
  end
86
144
  end
87
145
 
88
- class EagerLoadPolymorphicError < ActiveRecordError #:nodoc:
89
- def initialize(reflection)
90
- super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
146
+ class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
147
+ end
148
+
149
+ class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
150
+ end
151
+
152
+ # This error is raised when trying to eager load a polymorphic association using a JOIN.
153
+ # Eager loading polymorphic associations is only possible with
154
+ # {ActiveRecord::Relation#preload}[rdoc-ref:QueryMethods#preload].
155
+ class EagerLoadPolymorphicError < ActiveRecordError
156
+ def initialize(reflection = nil)
157
+ if reflection
158
+ super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
159
+ else
160
+ super("Eager load polymorphic error.")
161
+ end
91
162
  end
92
163
  end
93
164
 
94
165
  class ReadOnlyAssociation < ActiveRecordError #:nodoc:
95
- def initialize(reflection)
96
- super("Cannot add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.")
166
+ def initialize(reflection = nil)
167
+ if reflection
168
+ super("Cannot add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.")
169
+ else
170
+ super("Read-only reflection error.")
171
+ end
97
172
  end
98
173
  end
99
174
 
@@ -101,8 +176,12 @@ module ActiveRecord
101
176
  # (has_many, has_one) when there is at least 1 child associated instance.
102
177
  # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
103
178
  class DeleteRestrictionError < ActiveRecordError #:nodoc:
104
- def initialize(name)
105
- super("Cannot delete record because of dependent #{name}")
179
+ def initialize(name = nil)
180
+ if name
181
+ super("Cannot delete record because of dependent #{name}")
182
+ else
183
+ super("Delete restriction error.")
184
+ end
106
185
  end
107
186
  end
108
187
 
@@ -113,19 +192,19 @@ module ActiveRecord
113
192
 
114
193
  # These classes will be loaded when associations are created.
115
194
  # So there is no need to eager load them.
116
- autoload :Association, 'active_record/associations/association'
117
- autoload :SingularAssociation, 'active_record/associations/singular_association'
118
- autoload :CollectionAssociation, 'active_record/associations/collection_association'
119
- autoload :ForeignAssociation, 'active_record/associations/foreign_association'
120
- autoload :CollectionProxy, 'active_record/associations/collection_proxy'
195
+ autoload :Association
196
+ autoload :SingularAssociation
197
+ autoload :CollectionAssociation
198
+ autoload :ForeignAssociation
199
+ autoload :CollectionProxy
121
200
 
122
- autoload :BelongsToAssociation, 'active_record/associations/belongs_to_association'
123
- autoload :BelongsToPolymorphicAssociation, 'active_record/associations/belongs_to_polymorphic_association'
124
- autoload :HasManyAssociation, 'active_record/associations/has_many_association'
125
- autoload :HasManyThroughAssociation, 'active_record/associations/has_many_through_association'
126
- autoload :HasOneAssociation, 'active_record/associations/has_one_association'
127
- autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association'
128
- autoload :ThroughAssociation, 'active_record/associations/through_association'
201
+ autoload :BelongsToAssociation
202
+ autoload :BelongsToPolymorphicAssociation
203
+ autoload :HasManyAssociation
204
+ autoload :HasManyThroughAssociation
205
+ autoload :HasOneAssociation
206
+ autoload :HasOneThroughAssociation
207
+ autoload :ThroughAssociation
129
208
 
130
209
  module Builder #:nodoc:
131
210
  autoload :Association, 'active_record/associations/builder/association'
@@ -139,26 +218,20 @@ module ActiveRecord
139
218
  end
140
219
 
141
220
  eager_autoload do
142
- autoload :Preloader, 'active_record/associations/preloader'
143
- autoload :JoinDependency, 'active_record/associations/join_dependency'
144
- autoload :AssociationScope, 'active_record/associations/association_scope'
145
- autoload :AliasTracker, 'active_record/associations/alias_tracker'
146
- end
147
-
148
- # Clears out the association cache.
149
- def clear_association_cache #:nodoc:
150
- @association_cache.clear if persisted?
221
+ autoload :Preloader
222
+ autoload :JoinDependency
223
+ autoload :AssociationScope
224
+ autoload :AliasTracker
151
225
  end
152
226
 
153
- # :nodoc:
154
- attr_reader :association_cache
155
-
156
227
  # Returns the association instance for the given name, instantiating it if it doesn't already exist
157
228
  def association(name) #:nodoc:
158
229
  association = association_instance_get(name)
159
230
 
160
231
  if association.nil?
161
- raise AssociationNotFoundError.new(self, name) unless reflection = self.class._reflect_on_association(name)
232
+ unless reflection = self.class._reflect_on_association(name)
233
+ raise AssociationNotFoundError.new(self, name)
234
+ end
162
235
  association = reflection.association_class.new(self, reflection)
163
236
  association_instance_set(name, association)
164
237
  end
@@ -166,8 +239,32 @@ module ActiveRecord
166
239
  association
167
240
  end
168
241
 
242
+ def association_cached?(name) # :nodoc
243
+ @association_cache.key?(name)
244
+ end
245
+
246
+ def initialize_dup(*) # :nodoc:
247
+ @association_cache = {}
248
+ super
249
+ end
250
+
251
+ def reload(*) # :nodoc:
252
+ clear_association_cache
253
+ super
254
+ end
255
+
169
256
  private
170
- # Returns the specified association instance if it responds to :loaded?, nil otherwise.
257
+ # Clears out the association cache.
258
+ def clear_association_cache # :nodoc:
259
+ @association_cache.clear if persisted?
260
+ end
261
+
262
+ def init_internals # :nodoc:
263
+ @association_cache = {}
264
+ super
265
+ end
266
+
267
+ # Returns the specified association instance if it exists, nil otherwise.
171
268
  def association_instance_get(name)
172
269
  @association_cache[name]
173
270
  end
@@ -204,7 +301,7 @@ module ActiveRecord
204
301
  # === A word of warning
205
302
  #
206
303
  # Don't create associations that have the same name as instance methods of
207
- # <tt>ActiveRecord::Base</tt>. Since the association adds a method with that name to
304
+ # ActiveRecord::Base. Since the association adds a method with that name to
208
305
  # its model, it will override the inherited method and break things.
209
306
  # For instance, +attributes+ and +connection+ would be bad choices for association names.
210
307
  #
@@ -248,7 +345,6 @@ module ActiveRecord
248
345
  # others.find(*args) | X | X | X
249
346
  # others.exists? | X | X | X
250
347
  # others.distinct | X | X | X
251
- # others.uniq | X | X | X
252
348
  # others.reset | X | X | X
253
349
  #
254
350
  # === Overriding generated methods
@@ -267,7 +363,7 @@ module ActiveRecord
267
363
  # end
268
364
  #
269
365
  # If your model class is <tt>Project</tt>, the module is
270
- # named <tt>Project::GeneratedFeatureMethods</tt>. The GeneratedFeatureMethods module is
366
+ # named <tt>Project::GeneratedAssociationMethods</tt>. The +GeneratedAssociationMethods+ module is
271
367
  # included in the model class immediately after the (anonymous) generated attributes methods
272
368
  # module, meaning an association will override the methods for an attribute with the same name.
273
369
  #
@@ -275,12 +371,12 @@ module ActiveRecord
275
371
  #
276
372
  # Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
277
373
  # relationships between models. Each model uses an association to describe its role in
278
- # the relation. The +belongs_to+ association is always used in the model that has
374
+ # the relation. The #belongs_to association is always used in the model that has
279
375
  # the foreign key.
280
376
  #
281
377
  # === One-to-one
282
378
  #
283
- # Use +has_one+ in the base, and +belongs_to+ in the associated model.
379
+ # Use #has_one in the base, and #belongs_to in the associated model.
284
380
  #
285
381
  # class Employee < ActiveRecord::Base
286
382
  # has_one :office
@@ -291,7 +387,7 @@ module ActiveRecord
291
387
  #
292
388
  # === One-to-many
293
389
  #
294
- # Use +has_many+ in the base, and +belongs_to+ in the associated model.
390
+ # Use #has_many in the base, and #belongs_to in the associated model.
295
391
  #
296
392
  # class Manager < ActiveRecord::Base
297
393
  # has_many :employees
@@ -304,7 +400,7 @@ module ActiveRecord
304
400
  #
305
401
  # There are two ways to build a many-to-many relationship.
306
402
  #
307
- # The first way uses a +has_many+ association with the <tt>:through</tt> option and a join model, so
403
+ # The first way uses a #has_many association with the <tt>:through</tt> option and a join model, so
308
404
  # there are two stages of associations.
309
405
  #
310
406
  # class Assignment < ActiveRecord::Base
@@ -320,7 +416,7 @@ module ActiveRecord
320
416
  # has_many :programmers, through: :assignments
321
417
  # end
322
418
  #
323
- # For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table
419
+ # For the second way, use #has_and_belongs_to_many in both models. This requires a join table
324
420
  # that has no corresponding model or primary key.
325
421
  #
326
422
  # class Programmer < ActiveRecord::Base
@@ -332,13 +428,13 @@ module ActiveRecord
332
428
  #
333
429
  # Choosing which way to build a many-to-many relationship is not always simple.
334
430
  # If you need to work with the relationship model as its own entity,
335
- # use <tt>has_many :through</tt>. Use +has_and_belongs_to_many+ when working with legacy schemas or when
431
+ # use #has_many <tt>:through</tt>. Use #has_and_belongs_to_many when working with legacy schemas or when
336
432
  # you never work directly with the relationship itself.
337
433
  #
338
- # == Is it a +belongs_to+ or +has_one+ association?
434
+ # == Is it a #belongs_to or #has_one association?
339
435
  #
340
436
  # Both express a 1-1 relationship. The difference is mostly where to place the foreign
341
- # key, which goes on the table for the class declaring the +belongs_to+ relationship.
437
+ # key, which goes on the table for the class declaring the #belongs_to relationship.
342
438
  #
343
439
  # class User < ActiveRecord::Base
344
440
  # # I reference an account.
@@ -353,14 +449,14 @@ module ActiveRecord
353
449
  # The tables for these classes could look something like:
354
450
  #
355
451
  # CREATE TABLE users (
356
- # id int(11) NOT NULL auto_increment,
357
- # account_id int(11) default NULL,
452
+ # id int NOT NULL auto_increment,
453
+ # account_id int default NULL,
358
454
  # name varchar default NULL,
359
455
  # PRIMARY KEY (id)
360
456
  # )
361
457
  #
362
458
  # CREATE TABLE accounts (
363
- # id int(11) NOT NULL auto_increment,
459
+ # id int NOT NULL auto_increment,
364
460
  # name varchar default NULL,
365
461
  # PRIMARY KEY (id)
366
462
  # )
@@ -371,35 +467,35 @@ module ActiveRecord
371
467
  # there is some special behavior you should be aware of, mostly involving the saving of
372
468
  # associated objects.
373
469
  #
374
- # You can set the <tt>:autosave</tt> option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
375
- # <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association. Setting it
470
+ # You can set the <tt>:autosave</tt> option on a #has_one, #belongs_to,
471
+ # #has_many, or #has_and_belongs_to_many association. Setting it
376
472
  # to +true+ will _always_ save the members, whereas setting it to +false+ will
377
473
  # _never_ save the members. More details about <tt>:autosave</tt> option is available at
378
474
  # AutosaveAssociation.
379
475
  #
380
476
  # === One-to-one associations
381
477
  #
382
- # * Assigning an object to a +has_one+ association automatically saves that object and
478
+ # * Assigning an object to a #has_one association automatically saves that object and
383
479
  # the object being replaced (if there is one), in order to update their foreign
384
480
  # keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
385
481
  # * If either of these saves fail (due to one of the objects being invalid), an
386
- # <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
482
+ # ActiveRecord::RecordNotSaved exception is raised and the assignment is
387
483
  # cancelled.
388
- # * If you wish to assign an object to a +has_one+ association without saving it,
389
- # use the <tt>build_association</tt> method (documented below). The object being
484
+ # * If you wish to assign an object to a #has_one association without saving it,
485
+ # use the <tt>#build_association</tt> method (documented below). The object being
390
486
  # replaced will still be saved to update its foreign key.
391
- # * Assigning an object to a +belongs_to+ association does not save the object, since
487
+ # * Assigning an object to a #belongs_to association does not save the object, since
392
488
  # the foreign key field belongs on the parent. It does not save the parent either.
393
489
  #
394
490
  # === Collections
395
491
  #
396
- # * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically
492
+ # * Adding an object to a collection (#has_many or #has_and_belongs_to_many) automatically
397
493
  # saves that object, except if the parent object (the owner of the collection) is not yet
398
494
  # stored in the database.
399
495
  # * If saving any of the objects being added to a collection (via <tt>push</tt> or similar)
400
496
  # fails, then <tt>push</tt> returns +false+.
401
497
  # * If saving fails while replacing the collection (via <tt>association=</tt>), an
402
- # <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
498
+ # ActiveRecord::RecordNotSaved exception is raised and the assignment is
403
499
  # cancelled.
404
500
  # * You can add an object to a collection without automatically saving it by using the
405
501
  # <tt>collection.build</tt> method (documented below).
@@ -408,14 +504,14 @@ module ActiveRecord
408
504
  #
409
505
  # == Customizing the query
410
506
  #
411
- # \Associations are built from <tt>Relation</tt>s, and you can use the <tt>Relation</tt> syntax
507
+ # \Associations are built from <tt>Relation</tt>s, and you can use the Relation syntax
412
508
  # to customize them. For example, to add a condition:
413
509
  #
414
510
  # class Blog < ActiveRecord::Base
415
- # has_many :published_posts, -> { where published: true }, class_name: 'Post'
511
+ # has_many :published_posts, -> { where(published: true) }, class_name: 'Post'
416
512
  # end
417
513
  #
418
- # Inside the <tt>-> { ... }</tt> block you can use all of the usual <tt>Relation</tt> methods.
514
+ # Inside the <tt>-> { ... }</tt> block you can use all of the usual Relation methods.
419
515
  #
420
516
  # === Accessing the owner object
421
517
  #
@@ -424,7 +520,7 @@ module ActiveRecord
424
520
  # events that occur on the user's birthday:
425
521
  #
426
522
  # class User < ActiveRecord::Base
427
- # has_many :birthday_events, ->(user) { where starts_on: user.birthday }, class_name: 'Event'
523
+ # has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
428
524
  # end
429
525
  #
430
526
  # Note: Joining, eager loading and preloading of these associations is not fully possible.
@@ -503,8 +599,8 @@ module ActiveRecord
503
599
  #
504
600
  # * <tt>record.association(:items).owner</tt> - Returns the object the association is part of.
505
601
  # * <tt>record.association(:items).reflection</tt> - Returns the reflection object that describes the association.
506
- # * <tt>record.association(:items).target</tt> - Returns the associated object for +belongs_to+ and +has_one+, or
507
- # the collection of associated objects for +has_many+ and +has_and_belongs_to_many+.
602
+ # * <tt>record.association(:items).target</tt> - Returns the associated object for #belongs_to and #has_one, or
603
+ # the collection of associated objects for #has_many and #has_and_belongs_to_many.
508
604
  #
509
605
  # However, inside the actual extension code, you will not have access to the <tt>record</tt> as
510
606
  # above. In this case, you can access <tt>proxy_association</tt>. For example,
@@ -516,7 +612,7 @@ module ActiveRecord
516
612
  #
517
613
  # Has Many associations can be configured with the <tt>:through</tt> option to use an
518
614
  # explicit join model to retrieve the data. This operates similarly to a
519
- # +has_and_belongs_to_many+ association. The advantage is that you're able to add validations,
615
+ # #has_and_belongs_to_many association. The advantage is that you're able to add validations,
520
616
  # callbacks, and extra attributes on the join model. Consider the following schema:
521
617
  #
522
618
  # class Author < ActiveRecord::Base
@@ -533,7 +629,7 @@ module ActiveRecord
533
629
  # @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to
534
630
  # @author.books # selects all books by using the Authorship join model
535
631
  #
536
- # You can also go through a +has_many+ association on the join model:
632
+ # You can also go through a #has_many association on the join model:
537
633
  #
538
634
  # class Firm < ActiveRecord::Base
539
635
  # has_many :clients
@@ -553,7 +649,7 @@ module ActiveRecord
553
649
  # @firm.clients.flat_map { |c| c.invoices } # select all invoices for all clients of the firm
554
650
  # @firm.invoices # selects all invoices by going through the Client join model
555
651
  #
556
- # Similarly you can go through a +has_one+ association on the join model:
652
+ # Similarly you can go through a #has_one association on the join model:
557
653
  #
558
654
  # class Group < ActiveRecord::Base
559
655
  # has_many :users
@@ -573,7 +669,7 @@ module ActiveRecord
573
669
  # @group.users.collect { |u| u.avatar }.compact # select all avatars for all users in the group
574
670
  # @group.avatars # selects all avatars by going through the User join model.
575
671
  #
576
- # An important caveat with going through +has_one+ or +has_many+ associations on the
672
+ # An important caveat with going through #has_one or #has_many associations on the
577
673
  # join model is that these associations are *read-only*. For example, the following
578
674
  # would not work following the previous example:
579
675
  #
@@ -582,26 +678,26 @@ module ActiveRecord
582
678
  #
583
679
  # == Setting Inverses
584
680
  #
585
- # If you are using a +belongs_to+ on the join model, it is a good idea to set the
586
- # <tt>:inverse_of</tt> option on the +belongs_to+, which will mean that the following example
587
- # works correctly (where <tt>tags</tt> is a +has_many+ <tt>:through</tt> association):
681
+ # If you are using a #belongs_to on the join model, it is a good idea to set the
682
+ # <tt>:inverse_of</tt> option on the #belongs_to, which will mean that the following example
683
+ # works correctly (where <tt>tags</tt> is a #has_many <tt>:through</tt> association):
588
684
  #
589
685
  # @post = Post.first
590
686
  # @tag = @post.tags.build name: "ruby"
591
687
  # @tag.save
592
688
  #
593
- # The last line ought to save the through record (a <tt>Taggable</tt>). This will only work if the
689
+ # The last line ought to save the through record (a <tt>Tagging</tt>). This will only work if the
594
690
  # <tt>:inverse_of</tt> is set:
595
691
  #
596
- # class Taggable < ActiveRecord::Base
692
+ # class Tagging < ActiveRecord::Base
597
693
  # belongs_to :post
598
694
  # belongs_to :tag, inverse_of: :taggings
599
695
  # end
600
696
  #
601
697
  # If you do not set the <tt>:inverse_of</tt> record, the association will
602
698
  # do its best to match itself up with the correct inverse. Automatic
603
- # inverse detection only works on <tt>has_many</tt>, <tt>has_one</tt>, and
604
- # <tt>belongs_to</tt> associations.
699
+ # inverse detection only works on #has_many, #has_one, and
700
+ # #belongs_to associations.
605
701
  #
606
702
  # Extra options on the associations, as defined in the
607
703
  # <tt>AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS</tt> constant, will
@@ -614,7 +710,7 @@ module ActiveRecord
614
710
  # You can turn off the automatic detection of inverse associations by setting
615
711
  # the <tt>:inverse_of</tt> option to <tt>false</tt> like so:
616
712
  #
617
- # class Taggable < ActiveRecord::Base
713
+ # class Tagging < ActiveRecord::Base
618
714
  # belongs_to :tag, inverse_of: false
619
715
  # end
620
716
  #
@@ -664,7 +760,7 @@ module ActiveRecord
664
760
  # == Polymorphic \Associations
665
761
  #
666
762
  # Polymorphic associations on models are not restricted on what types of models they
667
- # can be associated with. Rather, they specify an interface that a +has_many+ association
763
+ # can be associated with. Rather, they specify an interface that a #has_many association
668
764
  # must adhere to.
669
765
  #
670
766
  # class Asset < ActiveRecord::Base
@@ -748,7 +844,7 @@ module ActiveRecord
748
844
  #
749
845
  # Post.includes(:author).each do |post|
750
846
  #
751
- # This references the name of the +belongs_to+ association that also used the <tt>:author</tt>
847
+ # This references the name of the #belongs_to association that also used the <tt>:author</tt>
752
848
  # symbol. After loading the posts, find will collect the +author_id+ from each one and load
753
849
  # all the referenced authors with one query. Doing so will cut down the number of queries
754
850
  # from 201 to 102.
@@ -759,7 +855,7 @@ module ActiveRecord
759
855
  #
760
856
  # This will load all comments with a single query. This reduces the total number of queries
761
857
  # to 3. In general, the number of queries will be 1 plus the number of associations
762
- # named (except if some of the associations are polymorphic +belongs_to+ - see below).
858
+ # named (except if some of the associations are polymorphic #belongs_to - see below).
763
859
  #
764
860
  # To include a deep hierarchy of associations, use a hash:
765
861
  #
@@ -799,7 +895,7 @@ module ActiveRecord
799
895
  # In this case it is usually more natural to include an association which has conditions defined on it:
800
896
  #
801
897
  # class Post < ActiveRecord::Base
802
- # has_many :approved_comments, -> { where approved: true }, class_name: 'Comment'
898
+ # has_many :approved_comments, -> { where(approved: true) }, class_name: 'Comment'
803
899
  # end
804
900
  #
805
901
  # Post.includes(:approved_comments)
@@ -831,7 +927,7 @@ module ActiveRecord
831
927
  # For example if all the addressables are either of class Person or Company then a total
832
928
  # of 3 queries will be executed. The list of addressable types to load is determined on
833
929
  # the back of the addresses loaded. This is not supported if Active Record has to fallback
834
- # to the previous implementation of eager loading and will raise <tt>ActiveRecord::EagerLoadPolymorphicError</tt>.
930
+ # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
835
931
  # The reason is that the parent model's type is a column value so its corresponding table
836
932
  # name cannot be put in the +FROM+/+JOIN+ clauses of that query.
837
933
  #
@@ -873,7 +969,7 @@ module ActiveRecord
873
969
  # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
874
970
  # INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
875
971
  #
876
- # If you wish to specify your own custom joins using <tt>joins</tt> method, those table
972
+ # If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table
877
973
  # names will take precedence over the eager associations:
878
974
  #
879
975
  # Post.joins(:comments).joins("inner join comments ...")
@@ -938,20 +1034,16 @@ module ActiveRecord
938
1034
  # The +traps+ association on +Dungeon+ and the +dungeon+ association on +Trap+ are
939
1035
  # the inverse of each other and the inverse of the +dungeon+ association on +EvilWizard+
940
1036
  # is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
941
- # Active Record doesn't know anything about these inverse relationships and so no object
942
- # loading optimization is possible. For example:
1037
+ # Active Record can guess the inverse of the association based on the name
1038
+ # of the class. The result is the following:
943
1039
  #
944
1040
  # d = Dungeon.first
945
1041
  # t = d.traps.first
946
- # d.level == t.dungeon.level # => true
947
- # d.level = 10
948
- # d.level == t.dungeon.level # => false
1042
+ # d.object_id == t.dungeon.object_id # => true
949
1043
  #
950
1044
  # The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to
951
- # the same object data from the database, but are actually different in-memory copies
952
- # of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell
953
- # Active Record about inverse relationships and it will optimise object loading. For
954
- # example, if we changed our model definitions to:
1045
+ # the same in-memory instance since the association matches the name of the class.
1046
+ # The result would be the same if we added +:inverse_of+ to our model definitions:
955
1047
  #
956
1048
  # class Dungeon < ActiveRecord::Base
957
1049
  # has_many :traps, inverse_of: :dungeon
@@ -966,20 +1058,19 @@ module ActiveRecord
966
1058
  # belongs_to :dungeon, inverse_of: :evil_wizard
967
1059
  # end
968
1060
  #
969
- # Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
970
- # in-memory instance and our final <tt>d.level == t.dungeon.level</tt> will return +true+.
971
- #
972
1061
  # There are limitations to <tt>:inverse_of</tt> support:
973
1062
  #
974
1063
  # * does not work with <tt>:through</tt> associations.
975
1064
  # * does not work with <tt>:polymorphic</tt> associations.
976
- # * for +belongs_to+ associations +has_many+ inverse associations are ignored.
1065
+ # * for #belongs_to associations #has_many inverse associations are ignored.
1066
+ #
1067
+ # For more information, see the documentation for the +:inverse_of+ option.
977
1068
  #
978
1069
  # == Deleting from associations
979
1070
  #
980
1071
  # === Dependent associations
981
1072
  #
982
- # +has_many+, +has_one+ and +belongs_to+ associations support the <tt>:dependent</tt> option.
1073
+ # #has_many, #has_one and #belongs_to associations support the <tt>:dependent</tt> option.
983
1074
  # This allows you to specify that associated records should be deleted when the owner is
984
1075
  # deleted.
985
1076
  #
@@ -1000,20 +1091,22 @@ module ActiveRecord
1000
1091
  # callbacks declared either before or after the <tt>:dependent</tt> option
1001
1092
  # can affect what it does.
1002
1093
  #
1094
+ # Note that <tt>:dependent</tt> option is ignored for #has_one <tt>:through</tt> associations.
1095
+ #
1003
1096
  # === Delete or destroy?
1004
1097
  #
1005
- # +has_many+ and +has_and_belongs_to_many+ associations have the methods <tt>destroy</tt>,
1098
+ # #has_many and #has_and_belongs_to_many associations have the methods <tt>destroy</tt>,
1006
1099
  # <tt>delete</tt>, <tt>destroy_all</tt> and <tt>delete_all</tt>.
1007
1100
  #
1008
- # For +has_and_belongs_to_many+, <tt>delete</tt> and <tt>destroy</tt> are the same: they
1101
+ # For #has_and_belongs_to_many, <tt>delete</tt> and <tt>destroy</tt> are the same: they
1009
1102
  # cause the records in the join table to be removed.
1010
1103
  #
1011
- # For +has_many+, <tt>destroy</tt> and <tt>destroy_all</tt> will always call the <tt>destroy</tt> method of the
1104
+ # For #has_many, <tt>destroy</tt> and <tt>destroy_all</tt> will always call the <tt>destroy</tt> method of the
1012
1105
  # record(s) being removed so that callbacks are run. However <tt>delete</tt> and <tt>delete_all</tt> will either
1013
1106
  # do the deletion according to the strategy specified by the <tt>:dependent</tt> option, or
1014
1107
  # if no <tt>:dependent</tt> option is given, then it will follow the default strategy.
1015
1108
  # The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for
1016
- # +has_many+ <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete
1109
+ # #has_many <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete
1017
1110
  # the join records, without running their callbacks).
1018
1111
  #
1019
1112
  # There is also a <tt>clear</tt> method which is the same as <tt>delete_all</tt>, except that
@@ -1021,13 +1114,13 @@ module ActiveRecord
1021
1114
  #
1022
1115
  # === What gets deleted?
1023
1116
  #
1024
- # There is a potential pitfall here: +has_and_belongs_to_many+ and +has_many+ <tt>:through</tt>
1117
+ # There is a potential pitfall here: #has_and_belongs_to_many and #has_many <tt>:through</tt>
1025
1118
  # associations have records in join tables, as well as the associated records. So when we
1026
1119
  # call one of these deletion methods, what exactly should be deleted?
1027
1120
  #
1028
1121
  # The answer is that it is assumed that deletion on an association is about removing the
1029
1122
  # <i>link</i> between the owner and the associated object(s), rather than necessarily the
1030
- # associated objects themselves. So with +has_and_belongs_to_many+ and +has_many+
1123
+ # associated objects themselves. So with #has_and_belongs_to_many and #has_many
1031
1124
  # <tt>:through</tt>, the join records will be deleted, but the associated records won't.
1032
1125
  #
1033
1126
  # This makes sense if you think about it: if you were to call <tt>post.tags.delete(Tag.find_by(name: 'food'))</tt>
@@ -1038,20 +1131,20 @@ module ActiveRecord
1038
1131
  # a person has many projects, and each project has many tasks. If we deleted one of a person's
1039
1132
  # tasks, we would probably not want the project to be deleted. In this scenario, the delete method
1040
1133
  # won't actually work: it can only be used if the association on the join model is a
1041
- # +belongs_to+. In other situations you are expected to perform operations directly on
1134
+ # #belongs_to. In other situations you are expected to perform operations directly on
1042
1135
  # either the associated records or the <tt>:through</tt> association.
1043
1136
  #
1044
- # With a regular +has_many+ there is no distinction between the "associated records"
1137
+ # With a regular #has_many there is no distinction between the "associated records"
1045
1138
  # and the "link", so there is only one choice for what gets deleted.
1046
1139
  #
1047
- # With +has_and_belongs_to_many+ and +has_many+ <tt>:through</tt>, if you want to delete the
1140
+ # With #has_and_belongs_to_many and #has_many <tt>:through</tt>, if you want to delete the
1048
1141
  # associated records themselves, you can always do something along the lines of
1049
1142
  # <tt>person.tasks.each(&:destroy)</tt>.
1050
1143
  #
1051
- # == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt>
1144
+ # == Type safety with ActiveRecord::AssociationTypeMismatch
1052
1145
  #
1053
1146
  # If you attempt to assign an object to an association that doesn't match the inferred
1054
- # or specified <tt>:class_name</tt>, you'll get an <tt>ActiveRecord::AssociationTypeMismatch</tt>.
1147
+ # or specified <tt>:class_name</tt>, you'll get an ActiveRecord::AssociationTypeMismatch.
1055
1148
  #
1056
1149
  # == Options
1057
1150
  #
@@ -1088,7 +1181,8 @@ module ActiveRecord
1088
1181
  # [collection=objects]
1089
1182
  # Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
1090
1183
  # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
1091
- # direct.
1184
+ # direct by default. You can specify <tt>dependent: :destroy</tt> or
1185
+ # <tt>dependent: :nullify</tt> to override this.
1092
1186
  # [collection_singular_ids]
1093
1187
  # Returns an array of the associated objects' ids
1094
1188
  # [collection_singular_ids=ids]
@@ -1105,10 +1199,10 @@ module ActiveRecord
1105
1199
  # [collection.size]
1106
1200
  # Returns the number of associated objects.
1107
1201
  # [collection.find(...)]
1108
- # Finds an associated object according to the same rules as <tt>ActiveRecord::Base.find</tt>.
1202
+ # Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
1109
1203
  # [collection.exists?(...)]
1110
1204
  # Checks whether an associated object with the given conditions exists.
1111
- # Uses the same rules as <tt>ActiveRecord::Base.exists?</tt>.
1205
+ # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1112
1206
  # [collection.build(attributes = {}, ...)]
1113
1207
  # Returns one or more new objects of the collection type that have been instantiated
1114
1208
  # with +attributes+ and linked to this object through a foreign key, but have not yet
@@ -1119,7 +1213,7 @@ module ActiveRecord
1119
1213
  # been saved (if it passed the validation). *Note*: This only works if the base model
1120
1214
  # already exists in the DB, not if it is a new (unsaved) record!
1121
1215
  # [collection.create!(attributes = {})]
1122
- # Does the same as <tt>collection.create</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
1216
+ # Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
1123
1217
  # if the record is invalid.
1124
1218
  #
1125
1219
  # === Example
@@ -1171,11 +1265,11 @@ module ActiveRecord
1171
1265
  # [:class_name]
1172
1266
  # Specify the class name of the association. Use it only if that name can't be inferred
1173
1267
  # from the association name. So <tt>has_many :products</tt> will by default be linked
1174
- # to the Product class, but if the real class name is SpecialProduct, you'll have to
1268
+ # to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
1175
1269
  # specify it with this option.
1176
1270
  # [:foreign_key]
1177
1271
  # Specify the foreign key used for the association. By default this is guessed to be the name
1178
- # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+
1272
+ # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
1179
1273
  # association will use "person_id" as the default <tt>:foreign_key</tt>.
1180
1274
  # [:foreign_type]
1181
1275
  # Specify the column used to store the associated object's type, if this is a polymorphic
@@ -1199,20 +1293,20 @@ module ActiveRecord
1199
1293
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
1200
1294
  #
1201
1295
  # If using with the <tt>:through</tt> option, the association on the join model must be
1202
- # a +belongs_to+, and the records which get deleted are the join records, rather than
1296
+ # a #belongs_to, and the records which get deleted are the join records, rather than
1203
1297
  # the associated records.
1204
1298
  # [:counter_cache]
1205
1299
  # This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
1206
- # when you customized the name of your <tt>:counter_cache</tt> on the <tt>belongs_to</tt> association.
1300
+ # when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association.
1207
1301
  # [:as]
1208
- # Specifies a polymorphic interface (See <tt>belongs_to</tt>).
1302
+ # Specifies a polymorphic interface (See #belongs_to).
1209
1303
  # [:through]
1210
1304
  # Specifies an association through which to perform the query. This can be any other type
1211
1305
  # of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
1212
1306
  # <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
1213
1307
  # source reflection.
1214
1308
  #
1215
- # If the association on the join model is a +belongs_to+, the collection can be modified
1309
+ # If the association on the join model is a #belongs_to, the collection can be modified
1216
1310
  # and the records on the <tt>:through</tt> model will be automatically created and removed
1217
1311
  # as appropriate. Otherwise, the collection is read-only, so you should manipulate the
1218
1312
  # <tt>:through</tt> association directly.
@@ -1223,13 +1317,13 @@ module ActiveRecord
1223
1317
  # the appropriate join model records when they are saved. (See the 'Association Join Models'
1224
1318
  # section above.)
1225
1319
  # [:source]
1226
- # Specifies the source association name used by <tt>has_many :through</tt> queries.
1320
+ # Specifies the source association name used by #has_many <tt>:through</tt> queries.
1227
1321
  # Only use it if the name cannot be inferred from the association.
1228
1322
  # <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
1229
1323
  # <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
1230
1324
  # [:source_type]
1231
- # Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
1232
- # association is a polymorphic +belongs_to+.
1325
+ # Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source
1326
+ # association is a polymorphic #belongs_to.
1233
1327
  # [:validate]
1234
1328
  # If +false+, don't validate the associated objects when saving the parent object. true by default.
1235
1329
  # [:autosave]
@@ -1239,18 +1333,23 @@ module ActiveRecord
1239
1333
  # +before_save+ callback. Because callbacks are run in the order they are defined, associated objects
1240
1334
  # may need to be explicitly saved in any user-defined +before_save+ callbacks.
1241
1335
  #
1242
- # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
1336
+ # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1337
+ # <tt>:autosave</tt> to <tt>true</tt>.
1243
1338
  # [:inverse_of]
1244
- # Specifies the name of the <tt>belongs_to</tt> association on the associated object
1245
- # that is the inverse of this <tt>has_many</tt> association. Does not work in combination
1339
+ # Specifies the name of the #belongs_to association on the associated object
1340
+ # that is the inverse of this #has_many association. Does not work in combination
1246
1341
  # with <tt>:through</tt> or <tt>:as</tt> options.
1247
1342
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1343
+ # [:extend]
1344
+ # Specifies a module or array of modules that will be extended into the association object returned.
1345
+ # Useful for defining methods on associations, especially when they should be shared between multiple
1346
+ # association objects.
1248
1347
  #
1249
1348
  # Option examples:
1250
- # has_many :comments, -> { order "posted_on" }
1251
- # has_many :comments, -> { includes :author }
1349
+ # has_many :comments, -> { order("posted_on") }
1350
+ # has_many :comments, -> { includes(:author) }
1252
1351
  # has_many :people, -> { where(deleted: false).order("name") }, class_name: "Person"
1253
- # has_many :tracks, -> { order "position" }, dependent: :destroy
1352
+ # has_many :tracks, -> { order("position") }, dependent: :destroy
1254
1353
  # has_many :comments, dependent: :nullify
1255
1354
  # has_many :tags, as: :taggable
1256
1355
  # has_many :reports, -> { readonly }
@@ -1262,8 +1361,8 @@ module ActiveRecord
1262
1361
 
1263
1362
  # Specifies a one-to-one association with another class. This method should only be used
1264
1363
  # if the other class contains the foreign key. If the current class contains the foreign key,
1265
- # then you should use +belongs_to+ instead. See also ActiveRecord::Associations::ClassMethods's overview
1266
- # on when to use +has_one+ and when to use +belongs_to+.
1364
+ # then you should use #belongs_to instead. See also ActiveRecord::Associations::ClassMethods's overview
1365
+ # on when to use #has_one and when to use #belongs_to.
1267
1366
  #
1268
1367
  # The following methods for retrieval and query of a single associated object will be added:
1269
1368
  #
@@ -1285,7 +1384,7 @@ module ActiveRecord
1285
1384
  # with +attributes+, linked to this object through a foreign key, and that
1286
1385
  # has already been saved (if it passed the validation).
1287
1386
  # [create_association!(attributes = {})]
1288
- # Does the same as <tt>create_association</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
1387
+ # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1289
1388
  # if the record is invalid.
1290
1389
  #
1291
1390
  # === Example
@@ -1326,9 +1425,11 @@ module ActiveRecord
1326
1425
  # * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Callbacks are not executed.
1327
1426
  # * <tt>:restrict_with_exception</tt> causes an exception to be raised if there is an associated record
1328
1427
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
1428
+ #
1429
+ # Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
1329
1430
  # [:foreign_key]
1330
1431
  # Specify the foreign key used for the association. By default this is guessed to be the name
1331
- # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association
1432
+ # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
1332
1433
  # will use "person_id" as the default <tt>:foreign_key</tt>.
1333
1434
  # [:foreign_type]
1334
1435
  # Specify the column used to store the associated object's type, if this is a polymorphic
@@ -1339,20 +1440,20 @@ module ActiveRecord
1339
1440
  # [:primary_key]
1340
1441
  # Specify the method that returns the primary key used for the association. By default this is +id+.
1341
1442
  # [:as]
1342
- # Specifies a polymorphic interface (See <tt>belongs_to</tt>).
1443
+ # Specifies a polymorphic interface (See #belongs_to).
1343
1444
  # [:through]
1344
1445
  # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
1345
1446
  # <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
1346
- # source reflection. You can only use a <tt>:through</tt> query through a <tt>has_one</tt>
1347
- # or <tt>belongs_to</tt> association on the join model.
1447
+ # source reflection. You can only use a <tt>:through</tt> query through a #has_one
1448
+ # or #belongs_to association on the join model.
1348
1449
  # [:source]
1349
- # Specifies the source association name used by <tt>has_one :through</tt> queries.
1450
+ # Specifies the source association name used by #has_one <tt>:through</tt> queries.
1350
1451
  # Only use it if the name cannot be inferred from the association.
1351
1452
  # <tt>has_one :favorite, through: :favorites</tt> will look for a
1352
1453
  # <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
1353
1454
  # [:source_type]
1354
- # Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
1355
- # association is a polymorphic +belongs_to+.
1455
+ # Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source
1456
+ # association is a polymorphic #belongs_to.
1356
1457
  # [:validate]
1357
1458
  # If +false+, don't validate the associated object when saving the parent object. +false+ by default.
1358
1459
  # [:autosave]
@@ -1360,10 +1461,11 @@ module ActiveRecord
1360
1461
  # when saving the parent object. If false, never save or destroy the associated object.
1361
1462
  # By default, only save the associated object if it's a new record.
1362
1463
  #
1363
- # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
1464
+ # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1465
+ # <tt>:autosave</tt> to <tt>true</tt>.
1364
1466
  # [:inverse_of]
1365
- # Specifies the name of the <tt>belongs_to</tt> association on the associated object
1366
- # that is the inverse of this <tt>has_one</tt> association. Does not work in combination
1467
+ # Specifies the name of the #belongs_to association on the associated object
1468
+ # that is the inverse of this #has_one association. Does not work in combination
1367
1469
  # with <tt>:through</tt> or <tt>:as</tt> options.
1368
1470
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1369
1471
  # [:required]
@@ -1375,12 +1477,12 @@ module ActiveRecord
1375
1477
  # has_one :credit_card, dependent: :destroy # destroys the associated credit card
1376
1478
  # has_one :credit_card, dependent: :nullify # updates the associated records foreign
1377
1479
  # # key value to NULL rather than destroying it
1378
- # has_one :last_comment, -> { order 'posted_on' }, class_name: "Comment"
1379
- # has_one :project_manager, -> { where role: 'project_manager' }, class_name: "Person"
1480
+ # has_one :last_comment, -> { order('posted_on') }, class_name: "Comment"
1481
+ # has_one :project_manager, -> { where(role: 'project_manager') }, class_name: "Person"
1380
1482
  # has_one :attachment, as: :attachable
1381
1483
  # has_one :boss, -> { readonly }
1382
1484
  # has_one :club, through: :membership
1383
- # has_one :primary_address, -> { where primary: true }, through: :addressables, source: :addressable
1485
+ # has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
1384
1486
  # has_one :credit_card, required: true
1385
1487
  def has_one(name, scope = nil, options = {})
1386
1488
  reflection = Builder::HasOne.build(self, name, scope, options)
@@ -1389,8 +1491,8 @@ module ActiveRecord
1389
1491
 
1390
1492
  # Specifies a one-to-one association with another class. This method should only be used
1391
1493
  # if this class contains the foreign key. If the other class contains the foreign key,
1392
- # then you should use +has_one+ instead. See also ActiveRecord::Associations::ClassMethods's overview
1393
- # on when to use +has_one+ and when to use +belongs_to+.
1494
+ # then you should use #has_one instead. See also ActiveRecord::Associations::ClassMethods's overview
1495
+ # on when to use #has_one and when to use #belongs_to.
1394
1496
  #
1395
1497
  # Methods will be added for retrieval and query for a single associated object, for which
1396
1498
  # this object holds an id:
@@ -1410,7 +1512,7 @@ module ActiveRecord
1410
1512
  # with +attributes+, linked to this object through a foreign key, and that
1411
1513
  # has already been saved (if it passed the validation).
1412
1514
  # [create_association!(attributes = {})]
1413
- # Does the same as <tt>create_association</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
1515
+ # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1414
1516
  # if the record is invalid.
1415
1517
  #
1416
1518
  # === Example
@@ -1430,7 +1532,7 @@ module ActiveRecord
1430
1532
  # when you access the associated object.
1431
1533
  #
1432
1534
  # Scope examples:
1433
- # belongs_to :user, -> { where(id: 2) }
1535
+ # belongs_to :firm, -> { where(id: 2) }
1434
1536
  # belongs_to :user, -> { joins(:friends) }
1435
1537
  # belongs_to :level, ->(level) { where("game_level > ?", level.current) }
1436
1538
  #
@@ -1457,12 +1559,12 @@ module ActiveRecord
1457
1559
  # [:dependent]
1458
1560
  # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
1459
1561
  # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
1460
- # This option should not be specified when <tt>belongs_to</tt> is used in conjunction with
1461
- # a <tt>has_many</tt> relationship on another class because of the potential to leave
1562
+ # This option should not be specified when #belongs_to is used in conjunction with
1563
+ # a #has_many relationship on another class because of the potential to leave
1462
1564
  # orphaned records behind.
1463
1565
  # [:counter_cache]
1464
- # Caches the number of belonging objects on the associate class through the use of +increment_counter+
1465
- # and +decrement_counter+. The counter cache is incremented when an object of this
1566
+ # Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
1567
+ # and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
1466
1568
  # class is created and decremented when it's destroyed. This requires that a column
1467
1569
  # named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
1468
1570
  # is used on the associate class (such as a Post class) - that is the migration for
@@ -1484,20 +1586,25 @@ module ActiveRecord
1484
1586
  # If false, never save or destroy the associated object.
1485
1587
  # By default, only save the associated object if it's a new record.
1486
1588
  #
1487
- # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
1589
+ # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
1590
+ # sets <tt>:autosave</tt> to <tt>true</tt>.
1488
1591
  # [:touch]
1489
1592
  # If true, the associated object will be touched (the updated_at/on attributes set to current time)
1490
1593
  # when this record is either saved or destroyed. If you specify a symbol, that attribute
1491
1594
  # will be updated with the current time in addition to the updated_at/on attribute.
1492
1595
  # [:inverse_of]
1493
- # Specifies the name of the <tt>has_one</tt> or <tt>has_many</tt> association on the associated
1494
- # object that is the inverse of this <tt>belongs_to</tt> association. Does not work in
1596
+ # Specifies the name of the #has_one or #has_many association on the associated
1597
+ # object that is the inverse of this #belongs_to association. Does not work in
1495
1598
  # combination with the <tt>:polymorphic</tt> options.
1496
1599
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1600
+ # [:optional]
1601
+ # When set to +true+, the association will not have its presence validated.
1497
1602
  # [:required]
1498
1603
  # When set to +true+, the association will also have its presence validated.
1499
1604
  # This will validate the association itself, not the id. You can use
1500
1605
  # +:inverse_of+ to avoid an extra query during validation.
1606
+ # NOTE: <tt>required</tt> is set to <tt>true</tt> by default and is deprecated. If
1607
+ # you don't want to have association presence validated, use <tt>optional: true</tt>.
1501
1608
  #
1502
1609
  # Option examples:
1503
1610
  # belongs_to :firm, foreign_key: "client_of"
@@ -1508,9 +1615,9 @@ module ActiveRecord
1508
1615
  # belongs_to :attachable, polymorphic: true
1509
1616
  # belongs_to :project, -> { readonly }
1510
1617
  # belongs_to :post, counter_cache: true
1511
- # belongs_to :company, touch: true
1618
+ # belongs_to :comment, touch: true
1512
1619
  # belongs_to :company, touch: :employees_last_updated_at
1513
- # belongs_to :company, required: true
1620
+ # belongs_to :user, optional: true
1514
1621
  def belongs_to(name, scope = nil, options = {})
1515
1622
  reflection = Builder::BelongsTo.build(self, name, scope, options)
1516
1623
  Reflection.add_reflection self, name, reflection
@@ -1533,12 +1640,9 @@ module ActiveRecord
1533
1640
  # The join table should not have a primary key or a model associated with it. You must manually generate the
1534
1641
  # join table with a migration such as this:
1535
1642
  #
1536
- # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
1643
+ # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[5.0]
1537
1644
  # def change
1538
- # create_table :developers_projects, id: false do |t|
1539
- # t.integer :developer_id
1540
- # t.integer :project_id
1541
- # end
1645
+ # create_join_table :developers, :projects
1542
1646
  # end
1543
1647
  # end
1544
1648
  #
@@ -1580,10 +1684,10 @@ module ActiveRecord
1580
1684
  # [collection.find(id)]
1581
1685
  # Finds an associated object responding to the +id+ and that
1582
1686
  # meets the condition that it has to be associated with this object.
1583
- # Uses the same rules as <tt>ActiveRecord::Base.find</tt>.
1687
+ # Uses the same rules as ActiveRecord::FinderMethods#find.
1584
1688
  # [collection.exists?(...)]
1585
1689
  # Checks whether an associated object with the given conditions exists.
1586
- # Uses the same rules as <tt>ActiveRecord::Base.exists?</tt>.
1690
+ # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1587
1691
  # [collection.build(attributes = {})]
1588
1692
  # Returns a new object of the collection type that has been instantiated
1589
1693
  # with +attributes+ and linked to this object through the join table, but has not yet been saved.
@@ -1618,7 +1722,7 @@ module ActiveRecord
1618
1722
  # query when you access the associated collection.
1619
1723
  #
1620
1724
  # Scope examples:
1621
- # has_and_belongs_to_many :projects, -> { includes :milestones, :manager }
1725
+ # has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
1622
1726
  # has_and_belongs_to_many :categories, ->(category) {
1623
1727
  # where("default_category = ?", category.name)
1624
1728
  # }
@@ -1647,19 +1751,17 @@ module ActiveRecord
1647
1751
  # [:join_table]
1648
1752
  # Specify the name of the join table if the default based on lexical order isn't what you want.
1649
1753
  # <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
1650
- # MUST be declared underneath any +has_and_belongs_to_many+ declaration in order to work.
1754
+ # MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
1651
1755
  # [:foreign_key]
1652
1756
  # Specify the foreign key used for the association. By default this is guessed to be the name
1653
1757
  # of this class in lower-case and "_id" suffixed. So a Person class that makes
1654
- # a +has_and_belongs_to_many+ association to Project will use "person_id" as the
1758
+ # a #has_and_belongs_to_many association to Project will use "person_id" as the
1655
1759
  # default <tt>:foreign_key</tt>.
1656
1760
  # [:association_foreign_key]
1657
1761
  # Specify the foreign key used for the association on the receiving side of the association.
1658
1762
  # By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
1659
- # So if a Person class makes a +has_and_belongs_to_many+ association to Project,
1763
+ # So if a Person class makes a #has_and_belongs_to_many association to Project,
1660
1764
  # the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
1661
- # [:readonly]
1662
- # If true, all the associated objects are readonly through the association.
1663
1765
  # [:validate]
1664
1766
  # If +false+, don't validate the associated objects when saving the parent object. +true+ by default.
1665
1767
  # [:autosave]
@@ -1668,11 +1770,12 @@ module ActiveRecord
1668
1770
  # If false, never save or destroy the associated objects.
1669
1771
  # By default, only save associated objects that are new records.
1670
1772
  #
1671
- # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
1773
+ # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1774
+ # <tt>:autosave</tt> to <tt>true</tt>.
1672
1775
  #
1673
1776
  # Option examples:
1674
1777
  # has_and_belongs_to_many :projects
1675
- # has_and_belongs_to_many :projects, -> { includes :milestones, :manager }
1778
+ # has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
1676
1779
  # has_and_belongs_to_many :nations, class_name: "Country"
1677
1780
  # has_and_belongs_to_many :categories, join_table: "prods_cats"
1678
1781
  # has_and_belongs_to_many :categories, -> { readonly }
@@ -1688,16 +1791,14 @@ module ActiveRecord
1688
1791
 
1689
1792
  join_model = builder.through_model
1690
1793
 
1691
- # FIXME: we should move this to the internal constants. Also people
1692
- # should never directly access this constant so I'm not happy about
1693
- # setting it.
1694
1794
  const_set join_model.name, join_model
1795
+ private_constant join_model.name
1695
1796
 
1696
1797
  middle_reflection = builder.middle_reflection join_model
1697
1798
 
1698
1799
  Builder::HasMany.define_callbacks self, middle_reflection
1699
1800
  Reflection.add_reflection self, middle_reflection.name, middle_reflection
1700
- middle_reflection.parent_reflection = [name.to_s, habtm_reflection]
1801
+ middle_reflection.parent_reflection = habtm_reflection
1701
1802
 
1702
1803
  include Module.new {
1703
1804
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -1718,7 +1819,7 @@ module ActiveRecord
1718
1819
  end
1719
1820
 
1720
1821
  has_many name, scope, hm_options, &extension
1721
- self._reflections[name.to_s].parent_reflection = [name.to_s, habtm_reflection]
1822
+ self._reflections[name.to_s].parent_reflection = habtm_reflection
1722
1823
  end
1723
1824
  end
1724
1825
  end