activerecord 4.2.0 → 5.0.0

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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1537 -789
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -8
  5. data/examples/performance.rb +2 -3
  6. data/examples/simple.rb +0 -1
  7. data/lib/active_record/aggregations.rb +37 -23
  8. data/lib/active_record/association_relation.rb +16 -3
  9. data/lib/active_record/associations/alias_tracker.rb +19 -16
  10. data/lib/active_record/associations/association.rb +23 -9
  11. data/lib/active_record/associations/association_scope.rb +74 -102
  12. data/lib/active_record/associations/belongs_to_association.rb +26 -29
  13. data/lib/active_record/associations/builder/association.rb +28 -34
  14. data/lib/active_record/associations/builder/belongs_to.rb +43 -18
  15. data/lib/active_record/associations/builder/collection_association.rb +12 -20
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +22 -15
  17. data/lib/active_record/associations/builder/has_many.rb +4 -4
  18. data/lib/active_record/associations/builder/has_one.rb +11 -6
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -10
  20. data/lib/active_record/associations/collection_association.rb +61 -33
  21. data/lib/active_record/associations/collection_proxy.rb +81 -35
  22. data/lib/active_record/associations/foreign_association.rb +11 -0
  23. data/lib/active_record/associations/has_many_association.rb +21 -57
  24. data/lib/active_record/associations/has_many_through_association.rb +15 -45
  25. data/lib/active_record/associations/has_one_association.rb +13 -5
  26. data/lib/active_record/associations/join_dependency/join_association.rb +20 -8
  27. data/lib/active_record/associations/join_dependency.rb +37 -21
  28. data/lib/active_record/associations/preloader/association.rb +51 -53
  29. data/lib/active_record/associations/preloader/collection_association.rb +0 -6
  30. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  31. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  32. data/lib/active_record/associations/preloader/through_association.rb +27 -14
  33. data/lib/active_record/associations/preloader.rb +18 -8
  34. data/lib/active_record/associations/singular_association.rb +8 -8
  35. data/lib/active_record/associations/through_association.rb +22 -9
  36. data/lib/active_record/associations.rb +321 -212
  37. data/lib/active_record/attribute/user_provided_default.rb +28 -0
  38. data/lib/active_record/attribute.rb +79 -15
  39. data/lib/active_record/attribute_assignment.rb +20 -141
  40. data/lib/active_record/attribute_decorators.rb +6 -5
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +6 -1
  42. data/lib/active_record/attribute_methods/dirty.rb +51 -81
  43. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  44. data/lib/active_record/attribute_methods/query.rb +2 -2
  45. data/lib/active_record/attribute_methods/read.rb +31 -59
  46. data/lib/active_record/attribute_methods/serialization.rb +13 -16
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +65 -14
  48. data/lib/active_record/attribute_methods/write.rb +14 -38
  49. data/lib/active_record/attribute_methods.rb +70 -45
  50. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  51. data/lib/active_record/attribute_set/builder.rb +37 -15
  52. data/lib/active_record/attribute_set.rb +34 -3
  53. data/lib/active_record/attributes.rb +199 -73
  54. data/lib/active_record/autosave_association.rb +73 -25
  55. data/lib/active_record/base.rb +35 -27
  56. data/lib/active_record/callbacks.rb +39 -43
  57. data/lib/active_record/coders/json.rb +1 -1
  58. data/lib/active_record/coders/yaml_column.rb +20 -8
  59. data/lib/active_record/collection_cache_key.rb +40 -0
  60. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +457 -181
  61. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
  62. data/lib/active_record/connection_adapters/abstract/database_statements.rb +83 -59
  63. data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -3
  64. data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -9
  65. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -4
  66. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
  67. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +246 -185
  68. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
  69. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +438 -136
  70. data/lib/active_record/connection_adapters/abstract/transaction.rb +53 -40
  71. data/lib/active_record/connection_adapters/abstract_adapter.rb +166 -66
  72. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +429 -335
  73. data/lib/active_record/connection_adapters/column.rb +28 -43
  74. data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
  75. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  76. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  77. data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
  78. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  79. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  80. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
  81. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
  82. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
  83. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  84. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -177
  85. data/lib/active_record/connection_adapters/postgresql/column.rb +5 -10
  86. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +11 -73
  87. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +27 -56
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -13
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
  95. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
  98. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
  99. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
  101. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +17 -5
  102. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
  103. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
  104. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
  106. data/lib/active_record/connection_adapters/postgresql/quoting.rb +26 -18
  107. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
  108. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
  109. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +248 -154
  111. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  112. data/lib/active_record/connection_adapters/postgresql_adapter.rb +258 -170
  113. data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
  114. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  115. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  116. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  117. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  118. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +150 -209
  119. data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
  120. data/lib/active_record/connection_handling.rb +38 -15
  121. data/lib/active_record/core.rb +109 -114
  122. data/lib/active_record/counter_cache.rb +14 -25
  123. data/lib/active_record/dynamic_matchers.rb +1 -20
  124. data/lib/active_record/enum.rb +115 -79
  125. data/lib/active_record/errors.rb +88 -48
  126. data/lib/active_record/explain_registry.rb +1 -1
  127. data/lib/active_record/explain_subscriber.rb +2 -2
  128. data/lib/active_record/fixture_set/file.rb +26 -5
  129. data/lib/active_record/fixtures.rb +84 -46
  130. data/lib/active_record/gem_version.rb +2 -2
  131. data/lib/active_record/inheritance.rb +32 -40
  132. data/lib/active_record/integration.rb +4 -4
  133. data/lib/active_record/internal_metadata.rb +56 -0
  134. data/lib/active_record/legacy_yaml_adapter.rb +46 -0
  135. data/lib/active_record/locale/en.yml +3 -2
  136. data/lib/active_record/locking/optimistic.rb +27 -25
  137. data/lib/active_record/locking/pessimistic.rb +1 -1
  138. data/lib/active_record/log_subscriber.rb +43 -21
  139. data/lib/active_record/migration/command_recorder.rb +59 -18
  140. data/lib/active_record/migration/compatibility.rb +126 -0
  141. data/lib/active_record/migration.rb +372 -114
  142. data/lib/active_record/model_schema.rb +128 -38
  143. data/lib/active_record/nested_attributes.rb +71 -32
  144. data/lib/active_record/no_touching.rb +1 -1
  145. data/lib/active_record/null_relation.rb +16 -8
  146. data/lib/active_record/persistence.rb +124 -80
  147. data/lib/active_record/query_cache.rb +15 -18
  148. data/lib/active_record/querying.rb +10 -9
  149. data/lib/active_record/railtie.rb +28 -19
  150. data/lib/active_record/railties/controller_runtime.rb +1 -1
  151. data/lib/active_record/railties/databases.rake +67 -51
  152. data/lib/active_record/readonly_attributes.rb +1 -1
  153. data/lib/active_record/reflection.rb +318 -139
  154. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  155. data/lib/active_record/relation/batches.rb +139 -34
  156. data/lib/active_record/relation/calculations.rb +80 -102
  157. data/lib/active_record/relation/delegation.rb +7 -20
  158. data/lib/active_record/relation/finder_methods.rb +167 -97
  159. data/lib/active_record/relation/from_clause.rb +32 -0
  160. data/lib/active_record/relation/merger.rb +38 -41
  161. data/lib/active_record/relation/predicate_builder/array_handler.rb +12 -16
  162. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
  163. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  164. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  165. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  166. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  167. data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
  168. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  169. data/lib/active_record/relation/predicate_builder.rb +124 -82
  170. data/lib/active_record/relation/query_attribute.rb +19 -0
  171. data/lib/active_record/relation/query_methods.rb +323 -257
  172. data/lib/active_record/relation/record_fetch_warning.rb +49 -0
  173. data/lib/active_record/relation/spawn_methods.rb +11 -10
  174. data/lib/active_record/relation/where_clause.rb +174 -0
  175. data/lib/active_record/relation/where_clause_factory.rb +38 -0
  176. data/lib/active_record/relation.rb +176 -115
  177. data/lib/active_record/result.rb +4 -3
  178. data/lib/active_record/runtime_registry.rb +1 -1
  179. data/lib/active_record/sanitization.rb +95 -66
  180. data/lib/active_record/schema.rb +26 -22
  181. data/lib/active_record/schema_dumper.rb +62 -38
  182. data/lib/active_record/schema_migration.rb +11 -17
  183. data/lib/active_record/scoping/default.rb +24 -9
  184. data/lib/active_record/scoping/named.rb +49 -28
  185. data/lib/active_record/scoping.rb +32 -15
  186. data/lib/active_record/secure_token.rb +38 -0
  187. data/lib/active_record/serialization.rb +2 -4
  188. data/lib/active_record/statement_cache.rb +16 -14
  189. data/lib/active_record/store.rb +8 -3
  190. data/lib/active_record/suppressor.rb +58 -0
  191. data/lib/active_record/table_metadata.rb +68 -0
  192. data/lib/active_record/tasks/database_tasks.rb +59 -42
  193. data/lib/active_record/tasks/mysql_database_tasks.rb +32 -26
  194. data/lib/active_record/tasks/postgresql_database_tasks.rb +29 -9
  195. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  196. data/lib/active_record/timestamp.rb +20 -9
  197. data/lib/active_record/touch_later.rb +58 -0
  198. data/lib/active_record/transactions.rb +159 -67
  199. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  200. data/lib/active_record/type/date.rb +2 -41
  201. data/lib/active_record/type/date_time.rb +2 -38
  202. data/lib/active_record/type/hash_lookup_type_map.rb +8 -2
  203. data/lib/active_record/type/internal/abstract_json.rb +29 -0
  204. data/lib/active_record/type/internal/timezone.rb +15 -0
  205. data/lib/active_record/type/serialized.rb +21 -14
  206. data/lib/active_record/type/time.rb +10 -16
  207. data/lib/active_record/type/type_map.rb +4 -4
  208. data/lib/active_record/type.rb +66 -17
  209. data/lib/active_record/type_caster/connection.rb +29 -0
  210. data/lib/active_record/type_caster/map.rb +19 -0
  211. data/lib/active_record/type_caster.rb +7 -0
  212. data/lib/active_record/validations/absence.rb +23 -0
  213. data/lib/active_record/validations/associated.rb +10 -3
  214. data/lib/active_record/validations/length.rb +24 -0
  215. data/lib/active_record/validations/presence.rb +11 -12
  216. data/lib/active_record/validations/uniqueness.rb +29 -18
  217. data/lib/active_record/validations.rb +33 -32
  218. data/lib/active_record.rb +9 -2
  219. data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
  220. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -6
  221. data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -7
  222. data/lib/rails/generators/active_record/migration.rb +7 -0
  223. data/lib/rails/generators/active_record/model/model_generator.rb +32 -15
  224. data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
  225. data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
  226. metadata +60 -34
  227. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  228. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  229. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
  230. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  231. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  232. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  233. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  234. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  235. data/lib/active_record/type/big_integer.rb +0 -13
  236. data/lib/active_record/type/binary.rb +0 -50
  237. data/lib/active_record/type/boolean.rb +0 -30
  238. data/lib/active_record/type/decimal.rb +0 -40
  239. data/lib/active_record/type/decimal_without_scale.rb +0 -11
  240. data/lib/active_record/type/decorator.rb +0 -14
  241. data/lib/active_record/type/float.rb +0 -19
  242. data/lib/active_record/type/integer.rb +0 -55
  243. data/lib/active_record/type/mutable.rb +0 -16
  244. data/lib/active_record/type/numeric.rb +0 -36
  245. data/lib/active_record/type/string.rb +0 -36
  246. data/lib/active_record/type/text.rb +0 -11
  247. data/lib/active_record/type/time_value.rb +0 -38
  248. data/lib/active_record/type/unsigned_integer.rb +0 -15
  249. data/lib/active_record/type/value.rb +0 -101
@@ -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,18 +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 :CollectionProxy, 'active_record/associations/collection_proxy'
195
+ autoload :Association
196
+ autoload :SingularAssociation
197
+ autoload :CollectionAssociation
198
+ autoload :ForeignAssociation
199
+ autoload :CollectionProxy
120
200
 
121
- autoload :BelongsToAssociation, 'active_record/associations/belongs_to_association'
122
- autoload :BelongsToPolymorphicAssociation, 'active_record/associations/belongs_to_polymorphic_association'
123
- autoload :HasManyAssociation, 'active_record/associations/has_many_association'
124
- autoload :HasManyThroughAssociation, 'active_record/associations/has_many_through_association'
125
- autoload :HasOneAssociation, 'active_record/associations/has_one_association'
126
- autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association'
127
- 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
128
208
 
129
209
  module Builder #:nodoc:
130
210
  autoload :Association, 'active_record/associations/builder/association'
@@ -138,26 +218,20 @@ module ActiveRecord
138
218
  end
139
219
 
140
220
  eager_autoload do
141
- autoload :Preloader, 'active_record/associations/preloader'
142
- autoload :JoinDependency, 'active_record/associations/join_dependency'
143
- autoload :AssociationScope, 'active_record/associations/association_scope'
144
- autoload :AliasTracker, 'active_record/associations/alias_tracker'
145
- end
146
-
147
- # Clears out the association cache.
148
- def clear_association_cache #:nodoc:
149
- @association_cache.clear if persisted?
221
+ autoload :Preloader
222
+ autoload :JoinDependency
223
+ autoload :AssociationScope
224
+ autoload :AliasTracker
150
225
  end
151
226
 
152
- # :nodoc:
153
- attr_reader :association_cache
154
-
155
227
  # Returns the association instance for the given name, instantiating it if it doesn't already exist
156
228
  def association(name) #:nodoc:
157
229
  association = association_instance_get(name)
158
230
 
159
231
  if association.nil?
160
- 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
161
235
  association = reflection.association_class.new(self, reflection)
162
236
  association_instance_set(name, association)
163
237
  end
@@ -165,8 +239,32 @@ module ActiveRecord
165
239
  association
166
240
  end
167
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
+
168
256
  private
169
- # 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.
170
268
  def association_instance_get(name)
171
269
  @association_cache[name]
172
270
  end
@@ -203,7 +301,7 @@ module ActiveRecord
203
301
  # === A word of warning
204
302
  #
205
303
  # Don't create associations that have the same name as instance methods of
206
- # <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
207
305
  # its model, it will override the inherited method and break things.
208
306
  # For instance, +attributes+ and +connection+ would be bad choices for association names.
209
307
  #
@@ -220,7 +318,7 @@ module ActiveRecord
220
318
  # create_other(attributes={}) | X | | X
221
319
  # create_other!(attributes={}) | X | | X
222
320
  #
223
- # ===Collection associations (one-to-many / many-to-many)
321
+ # === Collection associations (one-to-many / many-to-many)
224
322
  # | | | has_many
225
323
  # generated methods | habtm | has_many | :through
226
324
  # ----------------------------------+-------+----------+----------
@@ -247,7 +345,6 @@ module ActiveRecord
247
345
  # others.find(*args) | X | X | X
248
346
  # others.exists? | X | X | X
249
347
  # others.distinct | X | X | X
250
- # others.uniq | X | X | X
251
348
  # others.reset | X | X | X
252
349
  #
253
350
  # === Overriding generated methods
@@ -266,7 +363,7 @@ module ActiveRecord
266
363
  # end
267
364
  #
268
365
  # If your model class is <tt>Project</tt>, the module is
269
- # named <tt>Project::GeneratedFeatureMethods</tt>. The GeneratedFeatureMethods module is
366
+ # named <tt>Project::GeneratedAssociationMethods</tt>. The +GeneratedAssociationMethods+ module is
270
367
  # included in the model class immediately after the (anonymous) generated attributes methods
271
368
  # module, meaning an association will override the methods for an attribute with the same name.
272
369
  #
@@ -274,12 +371,12 @@ module ActiveRecord
274
371
  #
275
372
  # Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
276
373
  # relationships between models. Each model uses an association to describe its role in
277
- # 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
278
375
  # the foreign key.
279
376
  #
280
377
  # === One-to-one
281
378
  #
282
- # 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.
283
380
  #
284
381
  # class Employee < ActiveRecord::Base
285
382
  # has_one :office
@@ -290,7 +387,7 @@ module ActiveRecord
290
387
  #
291
388
  # === One-to-many
292
389
  #
293
- # 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.
294
391
  #
295
392
  # class Manager < ActiveRecord::Base
296
393
  # has_many :employees
@@ -303,7 +400,7 @@ module ActiveRecord
303
400
  #
304
401
  # There are two ways to build a many-to-many relationship.
305
402
  #
306
- # 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
307
404
  # there are two stages of associations.
308
405
  #
309
406
  # class Assignment < ActiveRecord::Base
@@ -319,7 +416,7 @@ module ActiveRecord
319
416
  # has_many :programmers, through: :assignments
320
417
  # end
321
418
  #
322
- # 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
323
420
  # that has no corresponding model or primary key.
324
421
  #
325
422
  # class Programmer < ActiveRecord::Base
@@ -331,13 +428,13 @@ module ActiveRecord
331
428
  #
332
429
  # Choosing which way to build a many-to-many relationship is not always simple.
333
430
  # If you need to work with the relationship model as its own entity,
334
- # 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
335
432
  # you never work directly with the relationship itself.
336
433
  #
337
- # == Is it a +belongs_to+ or +has_one+ association?
434
+ # == Is it a #belongs_to or #has_one association?
338
435
  #
339
436
  # Both express a 1-1 relationship. The difference is mostly where to place the foreign
340
- # 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.
341
438
  #
342
439
  # class User < ActiveRecord::Base
343
440
  # # I reference an account.
@@ -352,14 +449,14 @@ module ActiveRecord
352
449
  # The tables for these classes could look something like:
353
450
  #
354
451
  # CREATE TABLE users (
355
- # id int(11) NOT NULL auto_increment,
356
- # account_id int(11) default NULL,
452
+ # id int NOT NULL auto_increment,
453
+ # account_id int default NULL,
357
454
  # name varchar default NULL,
358
455
  # PRIMARY KEY (id)
359
456
  # )
360
457
  #
361
458
  # CREATE TABLE accounts (
362
- # id int(11) NOT NULL auto_increment,
459
+ # id int NOT NULL auto_increment,
363
460
  # name varchar default NULL,
364
461
  # PRIMARY KEY (id)
365
462
  # )
@@ -370,35 +467,35 @@ module ActiveRecord
370
467
  # there is some special behavior you should be aware of, mostly involving the saving of
371
468
  # associated objects.
372
469
  #
373
- # You can set the <tt>:autosave</tt> option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
374
- # <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
375
472
  # to +true+ will _always_ save the members, whereas setting it to +false+ will
376
473
  # _never_ save the members. More details about <tt>:autosave</tt> option is available at
377
474
  # AutosaveAssociation.
378
475
  #
379
476
  # === One-to-one associations
380
477
  #
381
- # * 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
382
479
  # the object being replaced (if there is one), in order to update their foreign
383
480
  # keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
384
481
  # * If either of these saves fail (due to one of the objects being invalid), an
385
- # <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
482
+ # ActiveRecord::RecordNotSaved exception is raised and the assignment is
386
483
  # cancelled.
387
- # * If you wish to assign an object to a +has_one+ association without saving it,
388
- # 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
389
486
  # replaced will still be saved to update its foreign key.
390
- # * 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
391
488
  # the foreign key field belongs on the parent. It does not save the parent either.
392
489
  #
393
490
  # === Collections
394
491
  #
395
- # * 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
396
493
  # saves that object, except if the parent object (the owner of the collection) is not yet
397
494
  # stored in the database.
398
495
  # * If saving any of the objects being added to a collection (via <tt>push</tt> or similar)
399
496
  # fails, then <tt>push</tt> returns +false+.
400
497
  # * If saving fails while replacing the collection (via <tt>association=</tt>), an
401
- # <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
498
+ # ActiveRecord::RecordNotSaved exception is raised and the assignment is
402
499
  # cancelled.
403
500
  # * You can add an object to a collection without automatically saving it by using the
404
501
  # <tt>collection.build</tt> method (documented below).
@@ -407,14 +504,14 @@ module ActiveRecord
407
504
  #
408
505
  # == Customizing the query
409
506
  #
410
- # \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> objects, and you can use the Relation syntax
411
508
  # to customize them. For example, to add a condition:
412
509
  #
413
510
  # class Blog < ActiveRecord::Base
414
- # has_many :published_posts, -> { where published: true }, class_name: 'Post'
511
+ # has_many :published_posts, -> { where(published: true) }, class_name: 'Post'
415
512
  # end
416
513
  #
417
- # 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.
418
515
  #
419
516
  # === Accessing the owner object
420
517
  #
@@ -423,7 +520,7 @@ module ActiveRecord
423
520
  # events that occur on the user's birthday:
424
521
  #
425
522
  # class User < ActiveRecord::Base
426
- # 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'
427
524
  # end
428
525
  #
429
526
  # Note: Joining, eager loading and preloading of these associations is not fully possible.
@@ -502,8 +599,8 @@ module ActiveRecord
502
599
  #
503
600
  # * <tt>record.association(:items).owner</tt> - Returns the object the association is part of.
504
601
  # * <tt>record.association(:items).reflection</tt> - Returns the reflection object that describes the association.
505
- # * <tt>record.association(:items).target</tt> - Returns the associated object for +belongs_to+ and +has_one+, or
506
- # 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.
507
604
  #
508
605
  # However, inside the actual extension code, you will not have access to the <tt>record</tt> as
509
606
  # above. In this case, you can access <tt>proxy_association</tt>. For example,
@@ -515,7 +612,7 @@ module ActiveRecord
515
612
  #
516
613
  # Has Many associations can be configured with the <tt>:through</tt> option to use an
517
614
  # explicit join model to retrieve the data. This operates similarly to a
518
- # +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,
519
616
  # callbacks, and extra attributes on the join model. Consider the following schema:
520
617
  #
521
618
  # class Author < ActiveRecord::Base
@@ -532,7 +629,7 @@ module ActiveRecord
532
629
  # @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to
533
630
  # @author.books # selects all books by using the Authorship join model
534
631
  #
535
- # 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:
536
633
  #
537
634
  # class Firm < ActiveRecord::Base
538
635
  # has_many :clients
@@ -552,7 +649,7 @@ module ActiveRecord
552
649
  # @firm.clients.flat_map { |c| c.invoices } # select all invoices for all clients of the firm
553
650
  # @firm.invoices # selects all invoices by going through the Client join model
554
651
  #
555
- # 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:
556
653
  #
557
654
  # class Group < ActiveRecord::Base
558
655
  # has_many :users
@@ -572,7 +669,7 @@ module ActiveRecord
572
669
  # @group.users.collect { |u| u.avatar }.compact # select all avatars for all users in the group
573
670
  # @group.avatars # selects all avatars by going through the User join model.
574
671
  #
575
- # 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
576
673
  # join model is that these associations are *read-only*. For example, the following
577
674
  # would not work following the previous example:
578
675
  #
@@ -581,26 +678,26 @@ module ActiveRecord
581
678
  #
582
679
  # == Setting Inverses
583
680
  #
584
- # If you are using a +belongs_to+ on the join model, it is a good idea to set the
585
- # <tt>:inverse_of</tt> option on the +belongs_to+, which will mean that the following example
586
- # 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):
587
684
  #
588
685
  # @post = Post.first
589
686
  # @tag = @post.tags.build name: "ruby"
590
687
  # @tag.save
591
688
  #
592
- # 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
593
690
  # <tt>:inverse_of</tt> is set:
594
691
  #
595
- # class Taggable < ActiveRecord::Base
692
+ # class Tagging < ActiveRecord::Base
596
693
  # belongs_to :post
597
694
  # belongs_to :tag, inverse_of: :taggings
598
695
  # end
599
696
  #
600
697
  # If you do not set the <tt>:inverse_of</tt> record, the association will
601
698
  # do its best to match itself up with the correct inverse. Automatic
602
- # inverse detection only works on <tt>has_many</tt>, <tt>has_one</tt>, and
603
- # <tt>belongs_to</tt> associations.
699
+ # inverse detection only works on #has_many, #has_one, and
700
+ # #belongs_to associations.
604
701
  #
605
702
  # Extra options on the associations, as defined in the
606
703
  # <tt>AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS</tt> constant, will
@@ -613,7 +710,7 @@ module ActiveRecord
613
710
  # You can turn off the automatic detection of inverse associations by setting
614
711
  # the <tt>:inverse_of</tt> option to <tt>false</tt> like so:
615
712
  #
616
- # class Taggable < ActiveRecord::Base
713
+ # class Tagging < ActiveRecord::Base
617
714
  # belongs_to :tag, inverse_of: false
618
715
  # end
619
716
  #
@@ -663,7 +760,7 @@ module ActiveRecord
663
760
  # == Polymorphic \Associations
664
761
  #
665
762
  # Polymorphic associations on models are not restricted on what types of models they
666
- # 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
667
764
  # must adhere to.
668
765
  #
669
766
  # class Asset < ActiveRecord::Base
@@ -747,7 +844,7 @@ module ActiveRecord
747
844
  #
748
845
  # Post.includes(:author).each do |post|
749
846
  #
750
- # 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>
751
848
  # symbol. After loading the posts, find will collect the +author_id+ from each one and load
752
849
  # all the referenced authors with one query. Doing so will cut down the number of queries
753
850
  # from 201 to 102.
@@ -758,7 +855,7 @@ module ActiveRecord
758
855
  #
759
856
  # This will load all comments with a single query. This reduces the total number of queries
760
857
  # to 3. In general, the number of queries will be 1 plus the number of associations
761
- # 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).
762
859
  #
763
860
  # To include a deep hierarchy of associations, use a hash:
764
861
  #
@@ -798,7 +895,7 @@ module ActiveRecord
798
895
  # In this case it is usually more natural to include an association which has conditions defined on it:
799
896
  #
800
897
  # class Post < ActiveRecord::Base
801
- # has_many :approved_comments, -> { where approved: true }, class_name: 'Comment'
898
+ # has_many :approved_comments, -> { where(approved: true) }, class_name: 'Comment'
802
899
  # end
803
900
  #
804
901
  # Post.includes(:approved_comments)
@@ -830,7 +927,7 @@ module ActiveRecord
830
927
  # For example if all the addressables are either of class Person or Company then a total
831
928
  # of 3 queries will be executed. The list of addressable types to load is determined on
832
929
  # the back of the addresses loaded. This is not supported if Active Record has to fallback
833
- # 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.
834
931
  # The reason is that the parent model's type is a column value so its corresponding table
835
932
  # name cannot be put in the +FROM+/+JOIN+ clauses of that query.
836
933
  #
@@ -872,7 +969,7 @@ module ActiveRecord
872
969
  # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
873
970
  # INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
874
971
  #
875
- # 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
876
973
  # names will take precedence over the eager associations:
877
974
  #
878
975
  # Post.joins(:comments).joins("inner join comments ...")
@@ -937,20 +1034,16 @@ module ActiveRecord
937
1034
  # The +traps+ association on +Dungeon+ and the +dungeon+ association on +Trap+ are
938
1035
  # the inverse of each other and the inverse of the +dungeon+ association on +EvilWizard+
939
1036
  # is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
940
- # Active Record doesn't know anything about these inverse relationships and so no object
941
- # 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:
942
1039
  #
943
1040
  # d = Dungeon.first
944
1041
  # t = d.traps.first
945
- # d.level == t.dungeon.level # => true
946
- # d.level = 10
947
- # d.level == t.dungeon.level # => false
1042
+ # d.object_id == t.dungeon.object_id # => true
948
1043
  #
949
1044
  # The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to
950
- # the same object data from the database, but are actually different in-memory copies
951
- # of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell
952
- # Active Record about inverse relationships and it will optimise object loading. For
953
- # 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:
954
1047
  #
955
1048
  # class Dungeon < ActiveRecord::Base
956
1049
  # has_many :traps, inverse_of: :dungeon
@@ -965,20 +1058,19 @@ module ActiveRecord
965
1058
  # belongs_to :dungeon, inverse_of: :evil_wizard
966
1059
  # end
967
1060
  #
968
- # Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
969
- # in-memory instance and our final <tt>d.level == t.dungeon.level</tt> will return +true+.
970
- #
971
1061
  # There are limitations to <tt>:inverse_of</tt> support:
972
1062
  #
973
1063
  # * does not work with <tt>:through</tt> associations.
974
1064
  # * does not work with <tt>:polymorphic</tt> associations.
975
- # * 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.
976
1068
  #
977
1069
  # == Deleting from associations
978
1070
  #
979
1071
  # === Dependent associations
980
1072
  #
981
- # +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.
982
1074
  # This allows you to specify that associated records should be deleted when the owner is
983
1075
  # deleted.
984
1076
  #
@@ -999,20 +1091,22 @@ module ActiveRecord
999
1091
  # callbacks declared either before or after the <tt>:dependent</tt> option
1000
1092
  # can affect what it does.
1001
1093
  #
1094
+ # Note that <tt>:dependent</tt> option is ignored for #has_one <tt>:through</tt> associations.
1095
+ #
1002
1096
  # === Delete or destroy?
1003
1097
  #
1004
- # +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>,
1005
1099
  # <tt>delete</tt>, <tt>destroy_all</tt> and <tt>delete_all</tt>.
1006
1100
  #
1007
- # 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
1008
1102
  # cause the records in the join table to be removed.
1009
1103
  #
1010
- # 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
1011
1105
  # record(s) being removed so that callbacks are run. However <tt>delete</tt> and <tt>delete_all</tt> will either
1012
1106
  # do the deletion according to the strategy specified by the <tt>:dependent</tt> option, or
1013
1107
  # if no <tt>:dependent</tt> option is given, then it will follow the default strategy.
1014
- # The default strategy is <tt>:nullify</tt> (set the foreign keys to <tt>nil</tt>), except for
1015
- # +has_many+ <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete
1108
+ # The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for
1109
+ # #has_many <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete
1016
1110
  # the join records, without running their callbacks).
1017
1111
  #
1018
1112
  # There is also a <tt>clear</tt> method which is the same as <tt>delete_all</tt>, except that
@@ -1020,13 +1114,13 @@ module ActiveRecord
1020
1114
  #
1021
1115
  # === What gets deleted?
1022
1116
  #
1023
- # 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>
1024
1118
  # associations have records in join tables, as well as the associated records. So when we
1025
1119
  # call one of these deletion methods, what exactly should be deleted?
1026
1120
  #
1027
1121
  # The answer is that it is assumed that deletion on an association is about removing the
1028
1122
  # <i>link</i> between the owner and the associated object(s), rather than necessarily the
1029
- # 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
1030
1124
  # <tt>:through</tt>, the join records will be deleted, but the associated records won't.
1031
1125
  #
1032
1126
  # This makes sense if you think about it: if you were to call <tt>post.tags.delete(Tag.find_by(name: 'food'))</tt>
@@ -1037,20 +1131,20 @@ module ActiveRecord
1037
1131
  # a person has many projects, and each project has many tasks. If we deleted one of a person's
1038
1132
  # tasks, we would probably not want the project to be deleted. In this scenario, the delete method
1039
1133
  # won't actually work: it can only be used if the association on the join model is a
1040
- # +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
1041
1135
  # either the associated records or the <tt>:through</tt> association.
1042
1136
  #
1043
- # 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"
1044
1138
  # and the "link", so there is only one choice for what gets deleted.
1045
1139
  #
1046
- # 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
1047
1141
  # associated records themselves, you can always do something along the lines of
1048
1142
  # <tt>person.tasks.each(&:destroy)</tt>.
1049
1143
  #
1050
- # == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt>
1144
+ # == Type safety with ActiveRecord::AssociationTypeMismatch
1051
1145
  #
1052
1146
  # If you attempt to assign an object to an association that doesn't match the inferred
1053
- # 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.
1054
1148
  #
1055
1149
  # == Options
1056
1150
  #
@@ -1070,6 +1164,7 @@ module ActiveRecord
1070
1164
  # Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
1071
1165
  # Note that this operation instantly fires update SQL without waiting for the save or update call on the
1072
1166
  # parent object, unless the parent object is a new record.
1167
+ # This will also run validations and callbacks of associated object(s).
1073
1168
  # [collection.delete(object, ...)]
1074
1169
  # Removes one or more objects from the collection by setting their foreign keys to +NULL+.
1075
1170
  # Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
@@ -1087,7 +1182,8 @@ module ActiveRecord
1087
1182
  # [collection=objects]
1088
1183
  # Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
1089
1184
  # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
1090
- # direct.
1185
+ # direct by default. You can specify <tt>dependent: :destroy</tt> or
1186
+ # <tt>dependent: :nullify</tt> to override this.
1091
1187
  # [collection_singular_ids]
1092
1188
  # Returns an array of the associated objects' ids
1093
1189
  # [collection_singular_ids=ids]
@@ -1104,10 +1200,10 @@ module ActiveRecord
1104
1200
  # [collection.size]
1105
1201
  # Returns the number of associated objects.
1106
1202
  # [collection.find(...)]
1107
- # Finds an associated object according to the same rules as <tt>ActiveRecord::Base.find</tt>.
1203
+ # Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
1108
1204
  # [collection.exists?(...)]
1109
1205
  # Checks whether an associated object with the given conditions exists.
1110
- # Uses the same rules as <tt>ActiveRecord::Base.exists?</tt>.
1206
+ # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1111
1207
  # [collection.build(attributes = {}, ...)]
1112
1208
  # Returns one or more new objects of the collection type that have been instantiated
1113
1209
  # with +attributes+ and linked to this object through a foreign key, but have not yet
@@ -1118,7 +1214,7 @@ module ActiveRecord
1118
1214
  # been saved (if it passed the validation). *Note*: This only works if the base model
1119
1215
  # already exists in the DB, not if it is a new (unsaved) record!
1120
1216
  # [collection.create!(attributes = {})]
1121
- # Does the same as <tt>collection.create</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
1217
+ # Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
1122
1218
  # if the record is invalid.
1123
1219
  #
1124
1220
  # === Example
@@ -1170,11 +1266,11 @@ module ActiveRecord
1170
1266
  # [:class_name]
1171
1267
  # Specify the class name of the association. Use it only if that name can't be inferred
1172
1268
  # from the association name. So <tt>has_many :products</tt> will by default be linked
1173
- # to the Product class, but if the real class name is SpecialProduct, you'll have to
1269
+ # to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
1174
1270
  # specify it with this option.
1175
1271
  # [:foreign_key]
1176
1272
  # Specify the foreign key used for the association. By default this is guessed to be the name
1177
- # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+
1273
+ # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
1178
1274
  # association will use "person_id" as the default <tt>:foreign_key</tt>.
1179
1275
  # [:foreign_type]
1180
1276
  # Specify the column used to store the associated object's type, if this is a polymorphic
@@ -1198,20 +1294,20 @@ module ActiveRecord
1198
1294
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
1199
1295
  #
1200
1296
  # If using with the <tt>:through</tt> option, the association on the join model must be
1201
- # a +belongs_to+, and the records which get deleted are the join records, rather than
1297
+ # a #belongs_to, and the records which get deleted are the join records, rather than
1202
1298
  # the associated records.
1203
1299
  # [:counter_cache]
1204
1300
  # This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
1205
- # when you customized the name of your <tt>:counter_cache</tt> on the <tt>belongs_to</tt> association.
1301
+ # when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association.
1206
1302
  # [:as]
1207
- # Specifies a polymorphic interface (See <tt>belongs_to</tt>).
1303
+ # Specifies a polymorphic interface (See #belongs_to).
1208
1304
  # [:through]
1209
1305
  # Specifies an association through which to perform the query. This can be any other type
1210
1306
  # of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
1211
1307
  # <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
1212
1308
  # source reflection.
1213
1309
  #
1214
- # If the association on the join model is a +belongs_to+, the collection can be modified
1310
+ # If the association on the join model is a #belongs_to, the collection can be modified
1215
1311
  # and the records on the <tt>:through</tt> model will be automatically created and removed
1216
1312
  # as appropriate. Otherwise, the collection is read-only, so you should manipulate the
1217
1313
  # <tt>:through</tt> association directly.
@@ -1222,15 +1318,16 @@ module ActiveRecord
1222
1318
  # the appropriate join model records when they are saved. (See the 'Association Join Models'
1223
1319
  # section above.)
1224
1320
  # [:source]
1225
- # Specifies the source association name used by <tt>has_many :through</tt> queries.
1321
+ # Specifies the source association name used by #has_many <tt>:through</tt> queries.
1226
1322
  # Only use it if the name cannot be inferred from the association.
1227
1323
  # <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
1228
1324
  # <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
1229
1325
  # [:source_type]
1230
- # Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
1231
- # association is a polymorphic +belongs_to+.
1326
+ # Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source
1327
+ # association is a polymorphic #belongs_to.
1232
1328
  # [:validate]
1233
- # If +false+, don't validate the associated objects when saving the parent object. true by default.
1329
+ # When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
1330
+ # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1234
1331
  # [:autosave]
1235
1332
  # If true, always save the associated objects or destroy them if marked for destruction,
1236
1333
  # when saving the parent object. If false, never save or destroy the associated objects.
@@ -1238,18 +1335,23 @@ module ActiveRecord
1238
1335
  # +before_save+ callback. Because callbacks are run in the order they are defined, associated objects
1239
1336
  # may need to be explicitly saved in any user-defined +before_save+ callbacks.
1240
1337
  #
1241
- # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
1338
+ # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1339
+ # <tt>:autosave</tt> to <tt>true</tt>.
1242
1340
  # [:inverse_of]
1243
- # Specifies the name of the <tt>belongs_to</tt> association on the associated object
1244
- # that is the inverse of this <tt>has_many</tt> association. Does not work in combination
1341
+ # Specifies the name of the #belongs_to association on the associated object
1342
+ # that is the inverse of this #has_many association. Does not work in combination
1245
1343
  # with <tt>:through</tt> or <tt>:as</tt> options.
1246
1344
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1345
+ # [:extend]
1346
+ # Specifies a module or array of modules that will be extended into the association object returned.
1347
+ # Useful for defining methods on associations, especially when they should be shared between multiple
1348
+ # association objects.
1247
1349
  #
1248
1350
  # Option examples:
1249
- # has_many :comments, -> { order "posted_on" }
1250
- # has_many :comments, -> { includes :author }
1351
+ # has_many :comments, -> { order("posted_on") }
1352
+ # has_many :comments, -> { includes(:author) }
1251
1353
  # has_many :people, -> { where(deleted: false).order("name") }, class_name: "Person"
1252
- # has_many :tracks, -> { order "position" }, dependent: :destroy
1354
+ # has_many :tracks, -> { order("position") }, dependent: :destroy
1253
1355
  # has_many :comments, dependent: :nullify
1254
1356
  # has_many :tags, as: :taggable
1255
1357
  # has_many :reports, -> { readonly }
@@ -1261,8 +1363,8 @@ module ActiveRecord
1261
1363
 
1262
1364
  # Specifies a one-to-one association with another class. This method should only be used
1263
1365
  # if the other class contains the foreign key. If the current class contains the foreign key,
1264
- # then you should use +belongs_to+ instead. See also ActiveRecord::Associations::ClassMethods's overview
1265
- # on when to use +has_one+ and when to use +belongs_to+.
1366
+ # then you should use #belongs_to instead. See also ActiveRecord::Associations::ClassMethods's overview
1367
+ # on when to use #has_one and when to use #belongs_to.
1266
1368
  #
1267
1369
  # The following methods for retrieval and query of a single associated object will be added:
1268
1370
  #
@@ -1284,7 +1386,7 @@ module ActiveRecord
1284
1386
  # with +attributes+, linked to this object through a foreign key, and that
1285
1387
  # has already been saved (if it passed the validation).
1286
1388
  # [create_association!(attributes = {})]
1287
- # Does the same as <tt>create_association</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
1389
+ # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1288
1390
  # if the record is invalid.
1289
1391
  #
1290
1392
  # === Example
@@ -1325,9 +1427,11 @@ module ActiveRecord
1325
1427
  # * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Callbacks are not executed.
1326
1428
  # * <tt>:restrict_with_exception</tt> causes an exception to be raised if there is an associated record
1327
1429
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
1430
+ #
1431
+ # Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
1328
1432
  # [:foreign_key]
1329
1433
  # Specify the foreign key used for the association. By default this is guessed to be the name
1330
- # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association
1434
+ # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
1331
1435
  # will use "person_id" as the default <tt>:foreign_key</tt>.
1332
1436
  # [:foreign_type]
1333
1437
  # Specify the column used to store the associated object's type, if this is a polymorphic
@@ -1338,31 +1442,33 @@ module ActiveRecord
1338
1442
  # [:primary_key]
1339
1443
  # Specify the method that returns the primary key used for the association. By default this is +id+.
1340
1444
  # [:as]
1341
- # Specifies a polymorphic interface (See <tt>belongs_to</tt>).
1445
+ # Specifies a polymorphic interface (See #belongs_to).
1342
1446
  # [:through]
1343
1447
  # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
1344
1448
  # <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
1345
- # source reflection. You can only use a <tt>:through</tt> query through a <tt>has_one</tt>
1346
- # or <tt>belongs_to</tt> association on the join model.
1449
+ # source reflection. You can only use a <tt>:through</tt> query through a #has_one
1450
+ # or #belongs_to association on the join model.
1347
1451
  # [:source]
1348
- # Specifies the source association name used by <tt>has_one :through</tt> queries.
1452
+ # Specifies the source association name used by #has_one <tt>:through</tt> queries.
1349
1453
  # Only use it if the name cannot be inferred from the association.
1350
1454
  # <tt>has_one :favorite, through: :favorites</tt> will look for a
1351
1455
  # <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
1352
1456
  # [:source_type]
1353
- # Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
1354
- # association is a polymorphic +belongs_to+.
1457
+ # Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source
1458
+ # association is a polymorphic #belongs_to.
1355
1459
  # [:validate]
1356
- # If +false+, don't validate the associated object when saving the parent object. +false+ by default.
1460
+ # When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
1461
+ # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1357
1462
  # [:autosave]
1358
1463
  # If true, always save the associated object or destroy it if marked for destruction,
1359
1464
  # when saving the parent object. If false, never save or destroy the associated object.
1360
1465
  # By default, only save the associated object if it's a new record.
1361
1466
  #
1362
- # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
1467
+ # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1468
+ # <tt>:autosave</tt> to <tt>true</tt>.
1363
1469
  # [:inverse_of]
1364
- # Specifies the name of the <tt>belongs_to</tt> association on the associated object
1365
- # that is the inverse of this <tt>has_one</tt> association. Does not work in combination
1470
+ # Specifies the name of the #belongs_to association on the associated object
1471
+ # that is the inverse of this #has_one association. Does not work in combination
1366
1472
  # with <tt>:through</tt> or <tt>:as</tt> options.
1367
1473
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1368
1474
  # [:required]
@@ -1374,12 +1480,12 @@ module ActiveRecord
1374
1480
  # has_one :credit_card, dependent: :destroy # destroys the associated credit card
1375
1481
  # has_one :credit_card, dependent: :nullify # updates the associated records foreign
1376
1482
  # # key value to NULL rather than destroying it
1377
- # has_one :last_comment, -> { order 'posted_on' }, class_name: "Comment"
1378
- # has_one :project_manager, -> { where role: 'project_manager' }, class_name: "Person"
1483
+ # has_one :last_comment, -> { order('posted_on') }, class_name: "Comment"
1484
+ # has_one :project_manager, -> { where(role: 'project_manager') }, class_name: "Person"
1379
1485
  # has_one :attachment, as: :attachable
1380
- # has_one :boss, readonly: :true
1486
+ # has_one :boss, -> { readonly }
1381
1487
  # has_one :club, through: :membership
1382
- # has_one :primary_address, -> { where primary: true }, through: :addressables, source: :addressable
1488
+ # has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
1383
1489
  # has_one :credit_card, required: true
1384
1490
  def has_one(name, scope = nil, options = {})
1385
1491
  reflection = Builder::HasOne.build(self, name, scope, options)
@@ -1388,8 +1494,8 @@ module ActiveRecord
1388
1494
 
1389
1495
  # Specifies a one-to-one association with another class. This method should only be used
1390
1496
  # if this class contains the foreign key. If the other class contains the foreign key,
1391
- # then you should use +has_one+ instead. See also ActiveRecord::Associations::ClassMethods's overview
1392
- # on when to use +has_one+ and when to use +belongs_to+.
1497
+ # then you should use #has_one instead. See also ActiveRecord::Associations::ClassMethods's overview
1498
+ # on when to use #has_one and when to use #belongs_to.
1393
1499
  #
1394
1500
  # Methods will be added for retrieval and query for a single associated object, for which
1395
1501
  # this object holds an id:
@@ -1409,7 +1515,7 @@ module ActiveRecord
1409
1515
  # with +attributes+, linked to this object through a foreign key, and that
1410
1516
  # has already been saved (if it passed the validation).
1411
1517
  # [create_association!(attributes = {})]
1412
- # Does the same as <tt>create_association</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
1518
+ # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1413
1519
  # if the record is invalid.
1414
1520
  #
1415
1521
  # === Example
@@ -1429,7 +1535,7 @@ module ActiveRecord
1429
1535
  # when you access the associated object.
1430
1536
  #
1431
1537
  # Scope examples:
1432
- # belongs_to :user, -> { where(id: 2) }
1538
+ # belongs_to :firm, -> { where(id: 2) }
1433
1539
  # belongs_to :user, -> { joins(:friends) }
1434
1540
  # belongs_to :level, ->(level) { where("game_level > ?", level.current) }
1435
1541
  #
@@ -1456,12 +1562,12 @@ module ActiveRecord
1456
1562
  # [:dependent]
1457
1563
  # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
1458
1564
  # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
1459
- # This option should not be specified when <tt>belongs_to</tt> is used in conjunction with
1460
- # a <tt>has_many</tt> relationship on another class because of the potential to leave
1565
+ # This option should not be specified when #belongs_to is used in conjunction with
1566
+ # a #has_many relationship on another class because of the potential to leave
1461
1567
  # orphaned records behind.
1462
1568
  # [:counter_cache]
1463
- # Caches the number of belonging objects on the associate class through the use of +increment_counter+
1464
- # and +decrement_counter+. The counter cache is incremented when an object of this
1569
+ # Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
1570
+ # and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
1465
1571
  # class is created and decremented when it's destroyed. This requires that a column
1466
1572
  # named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
1467
1573
  # is used on the associate class (such as a Post class) - that is the migration for
@@ -1476,27 +1582,35 @@ module ActiveRecord
1476
1582
  # Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
1477
1583
  # to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
1478
1584
  # [:validate]
1479
- # If +false+, don't validate the associated objects when saving the parent object. +false+ by default.
1585
+ # When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
1586
+ # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1480
1587
  # [:autosave]
1481
1588
  # If true, always save the associated object or destroy it if marked for destruction, when
1482
1589
  # saving the parent object.
1483
1590
  # If false, never save or destroy the associated object.
1484
1591
  # By default, only save the associated object if it's a new record.
1485
1592
  #
1486
- # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
1593
+ # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
1594
+ # sets <tt>:autosave</tt> to <tt>true</tt>.
1487
1595
  # [:touch]
1488
1596
  # If true, the associated object will be touched (the updated_at/on attributes set to current time)
1489
1597
  # when this record is either saved or destroyed. If you specify a symbol, that attribute
1490
1598
  # will be updated with the current time in addition to the updated_at/on attribute.
1599
+ # Please note that with touching no validation is performed and only the +after_touch+,
1600
+ # +after_commit+ and +after_rollback+ callbacks are executed.
1491
1601
  # [:inverse_of]
1492
- # Specifies the name of the <tt>has_one</tt> or <tt>has_many</tt> association on the associated
1493
- # object that is the inverse of this <tt>belongs_to</tt> association. Does not work in
1602
+ # Specifies the name of the #has_one or #has_many association on the associated
1603
+ # object that is the inverse of this #belongs_to association. Does not work in
1494
1604
  # combination with the <tt>:polymorphic</tt> options.
1495
1605
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1606
+ # [:optional]
1607
+ # When set to +true+, the association will not have its presence validated.
1496
1608
  # [:required]
1497
1609
  # When set to +true+, the association will also have its presence validated.
1498
1610
  # This will validate the association itself, not the id. You can use
1499
1611
  # +:inverse_of+ to avoid an extra query during validation.
1612
+ # NOTE: <tt>required</tt> is set to <tt>true</tt> by default and is deprecated. If
1613
+ # you don't want to have association presence validated, use <tt>optional: true</tt>.
1500
1614
  #
1501
1615
  # Option examples:
1502
1616
  # belongs_to :firm, foreign_key: "client_of"
@@ -1505,11 +1619,11 @@ module ActiveRecord
1505
1619
  # belongs_to :valid_coupon, ->(o) { where "discounts > ?", o.payments_count },
1506
1620
  # class_name: "Coupon", foreign_key: "coupon_id"
1507
1621
  # belongs_to :attachable, polymorphic: true
1508
- # belongs_to :project, readonly: true
1622
+ # belongs_to :project, -> { readonly }
1509
1623
  # belongs_to :post, counter_cache: true
1510
- # belongs_to :company, touch: true
1624
+ # belongs_to :comment, touch: true
1511
1625
  # belongs_to :company, touch: :employees_last_updated_at
1512
- # belongs_to :company, required: true
1626
+ # belongs_to :user, optional: true
1513
1627
  def belongs_to(name, scope = nil, options = {})
1514
1628
  reflection = Builder::BelongsTo.build(self, name, scope, options)
1515
1629
  Reflection.add_reflection self, name, reflection
@@ -1532,12 +1646,9 @@ module ActiveRecord
1532
1646
  # The join table should not have a primary key or a model associated with it. You must manually generate the
1533
1647
  # join table with a migration such as this:
1534
1648
  #
1535
- # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
1649
+ # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[5.0]
1536
1650
  # def change
1537
- # create_table :developers_projects, id: false do |t|
1538
- # t.integer :developer_id
1539
- # t.integer :project_id
1540
- # end
1651
+ # create_join_table :developers, :projects
1541
1652
  # end
1542
1653
  # end
1543
1654
  #
@@ -1579,10 +1690,10 @@ module ActiveRecord
1579
1690
  # [collection.find(id)]
1580
1691
  # Finds an associated object responding to the +id+ and that
1581
1692
  # meets the condition that it has to be associated with this object.
1582
- # Uses the same rules as <tt>ActiveRecord::Base.find</tt>.
1693
+ # Uses the same rules as ActiveRecord::FinderMethods#find.
1583
1694
  # [collection.exists?(...)]
1584
1695
  # Checks whether an associated object with the given conditions exists.
1585
- # Uses the same rules as <tt>ActiveRecord::Base.exists?</tt>.
1696
+ # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1586
1697
  # [collection.build(attributes = {})]
1587
1698
  # Returns a new object of the collection type that has been instantiated
1588
1699
  # with +attributes+ and linked to this object through the join table, but has not yet been saved.
@@ -1617,7 +1728,7 @@ module ActiveRecord
1617
1728
  # query when you access the associated collection.
1618
1729
  #
1619
1730
  # Scope examples:
1620
- # has_and_belongs_to_many :projects, -> { includes :milestones, :manager }
1731
+ # has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
1621
1732
  # has_and_belongs_to_many :categories, ->(category) {
1622
1733
  # where("default_category = ?", category.name)
1623
1734
  # }
@@ -1646,32 +1757,32 @@ module ActiveRecord
1646
1757
  # [:join_table]
1647
1758
  # Specify the name of the join table if the default based on lexical order isn't what you want.
1648
1759
  # <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
1649
- # MUST be declared underneath any +has_and_belongs_to_many+ declaration in order to work.
1760
+ # MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
1650
1761
  # [:foreign_key]
1651
1762
  # Specify the foreign key used for the association. By default this is guessed to be the name
1652
1763
  # of this class in lower-case and "_id" suffixed. So a Person class that makes
1653
- # a +has_and_belongs_to_many+ association to Project will use "person_id" as the
1764
+ # a #has_and_belongs_to_many association to Project will use "person_id" as the
1654
1765
  # default <tt>:foreign_key</tt>.
1655
1766
  # [:association_foreign_key]
1656
1767
  # Specify the foreign key used for the association on the receiving side of the association.
1657
1768
  # By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
1658
- # So if a Person class makes a +has_and_belongs_to_many+ association to Project,
1769
+ # So if a Person class makes a #has_and_belongs_to_many association to Project,
1659
1770
  # the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
1660
- # [:readonly]
1661
- # If true, all the associated objects are readonly through the association.
1662
1771
  # [:validate]
1663
- # If +false+, don't validate the associated objects when saving the parent object. +true+ by default.
1772
+ # When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
1773
+ # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1664
1774
  # [:autosave]
1665
1775
  # If true, always save the associated objects or destroy them if marked for destruction, when
1666
1776
  # saving the parent object.
1667
1777
  # If false, never save or destroy the associated objects.
1668
1778
  # By default, only save associated objects that are new records.
1669
1779
  #
1670
- # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
1780
+ # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1781
+ # <tt>:autosave</tt> to <tt>true</tt>.
1671
1782
  #
1672
1783
  # Option examples:
1673
1784
  # has_and_belongs_to_many :projects
1674
- # has_and_belongs_to_many :projects, -> { includes :milestones, :manager }
1785
+ # has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
1675
1786
  # has_and_belongs_to_many :nations, class_name: "Country"
1676
1787
  # has_and_belongs_to_many :categories, join_table: "prods_cats"
1677
1788
  # has_and_belongs_to_many :categories, -> { readonly }
@@ -1687,16 +1798,14 @@ module ActiveRecord
1687
1798
 
1688
1799
  join_model = builder.through_model
1689
1800
 
1690
- # FIXME: we should move this to the internal constants. Also people
1691
- # should never directly access this constant so I'm not happy about
1692
- # setting it.
1693
1801
  const_set join_model.name, join_model
1802
+ private_constant join_model.name
1694
1803
 
1695
1804
  middle_reflection = builder.middle_reflection join_model
1696
1805
 
1697
1806
  Builder::HasMany.define_callbacks self, middle_reflection
1698
1807
  Reflection.add_reflection self, middle_reflection.name, middle_reflection
1699
- middle_reflection.parent_reflection = [name.to_s, habtm_reflection]
1808
+ middle_reflection.parent_reflection = habtm_reflection
1700
1809
 
1701
1810
  include Module.new {
1702
1811
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -1712,12 +1821,12 @@ module ActiveRecord
1712
1821
  hm_options[:through] = middle_reflection.name
1713
1822
  hm_options[:source] = join_model.right_reflection.name
1714
1823
 
1715
- [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name].each do |k|
1824
+ [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k|
1716
1825
  hm_options[k] = options[k] if options.key? k
1717
1826
  end
1718
1827
 
1719
1828
  has_many name, scope, hm_options, &extension
1720
- self._reflections[name.to_s].parent_reflection = [name.to_s, habtm_reflection]
1829
+ self._reflections[name.to_s].parent_reflection = habtm_reflection
1721
1830
  end
1722
1831
  end
1723
1832
  end