activerecord 5.1.7 → 5.2.4.3

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 (261) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +556 -685
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -5
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record.rb +11 -4
  8. data/lib/active_record/aggregations.rb +6 -5
  9. data/lib/active_record/association_relation.rb +7 -5
  10. data/lib/active_record/associations.rb +40 -63
  11. data/lib/active_record/associations/alias_tracker.rb +19 -27
  12. data/lib/active_record/associations/association.rb +41 -37
  13. data/lib/active_record/associations/association_scope.rb +38 -50
  14. data/lib/active_record/associations/belongs_to_association.rb +27 -8
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  16. data/lib/active_record/associations/builder/association.rb +4 -7
  17. data/lib/active_record/associations/builder/belongs_to.rb +12 -4
  18. data/lib/active_record/associations/builder/collection_association.rb +3 -3
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  20. data/lib/active_record/associations/builder/has_many.rb +2 -0
  21. data/lib/active_record/associations/builder/has_one.rb +2 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  23. data/lib/active_record/associations/collection_association.rb +59 -47
  24. data/lib/active_record/associations/collection_proxy.rb +20 -49
  25. data/lib/active_record/associations/foreign_association.rb +2 -0
  26. data/lib/active_record/associations/has_many_association.rb +12 -1
  27. data/lib/active_record/associations/has_many_through_association.rb +36 -30
  28. data/lib/active_record/associations/has_one_association.rb +12 -1
  29. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  30. data/lib/active_record/associations/join_dependency.rb +48 -93
  31. data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
  32. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  33. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  34. data/lib/active_record/associations/preloader.rb +18 -38
  35. data/lib/active_record/associations/preloader/association.rb +45 -61
  36. data/lib/active_record/associations/preloader/through_association.rb +71 -79
  37. data/lib/active_record/associations/singular_association.rb +14 -16
  38. data/lib/active_record/associations/through_association.rb +26 -11
  39. data/lib/active_record/attribute_assignment.rb +2 -5
  40. data/lib/active_record/attribute_decorators.rb +3 -2
  41. data/lib/active_record/attribute_methods.rb +65 -24
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +30 -214
  44. data/lib/active_record/attribute_methods/primary_key.rb +7 -6
  45. data/lib/active_record/attribute_methods/query.rb +2 -0
  46. data/lib/active_record/attribute_methods/read.rb +9 -3
  47. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  49. data/lib/active_record/attribute_methods/write.rb +21 -9
  50. data/lib/active_record/attributes.rb +6 -5
  51. data/lib/active_record/autosave_association.rb +35 -19
  52. data/lib/active_record/base.rb +2 -0
  53. data/lib/active_record/callbacks.rb +8 -6
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +2 -0
  56. data/lib/active_record/collection_cache_key.rb +12 -8
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +139 -41
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -31
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +64 -6
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
  70. data/lib/active_record/connection_adapters/column.rb +3 -1
  71. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
  73. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -2
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  101. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +233 -111
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -73
  118. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +22 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +81 -94
  127. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  128. data/lib/active_record/connection_handling.rb +4 -2
  129. data/lib/active_record/core.rb +41 -61
  130. data/lib/active_record/counter_cache.rb +10 -3
  131. data/lib/active_record/define_callbacks.rb +5 -3
  132. data/lib/active_record/dynamic_matchers.rb +9 -9
  133. data/lib/active_record/enum.rb +18 -13
  134. data/lib/active_record/errors.rb +42 -3
  135. data/lib/active_record/explain.rb +3 -1
  136. data/lib/active_record/explain_registry.rb +2 -0
  137. data/lib/active_record/explain_subscriber.rb +2 -0
  138. data/lib/active_record/fixture_set/file.rb +2 -0
  139. data/lib/active_record/fixtures.rb +67 -60
  140. data/lib/active_record/gem_version.rb +5 -3
  141. data/lib/active_record/inheritance.rb +49 -19
  142. data/lib/active_record/integration.rb +58 -19
  143. data/lib/active_record/internal_metadata.rb +2 -0
  144. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  145. data/lib/active_record/locking/optimistic.rb +14 -17
  146. data/lib/active_record/locking/pessimistic.rb +9 -6
  147. data/lib/active_record/log_subscriber.rb +43 -0
  148. data/lib/active_record/migration.rb +189 -139
  149. data/lib/active_record/migration/command_recorder.rb +11 -9
  150. data/lib/active_record/migration/compatibility.rb +47 -9
  151. data/lib/active_record/migration/join_table.rb +2 -0
  152. data/lib/active_record/model_schema.rb +16 -21
  153. data/lib/active_record/nested_attributes.rb +18 -6
  154. data/lib/active_record/no_touching.rb +3 -1
  155. data/lib/active_record/null_relation.rb +2 -0
  156. data/lib/active_record/persistence.rb +167 -16
  157. data/lib/active_record/query_cache.rb +6 -8
  158. data/lib/active_record/querying.rb +4 -2
  159. data/lib/active_record/railtie.rb +62 -6
  160. data/lib/active_record/railties/console_sandbox.rb +2 -0
  161. data/lib/active_record/railties/controller_runtime.rb +2 -0
  162. data/lib/active_record/railties/databases.rake +46 -36
  163. data/lib/active_record/readonly_attributes.rb +3 -2
  164. data/lib/active_record/reflection.rb +108 -194
  165. data/lib/active_record/relation.rb +120 -214
  166. data/lib/active_record/relation/batches.rb +20 -5
  167. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  168. data/lib/active_record/relation/calculations.rb +45 -19
  169. data/lib/active_record/relation/delegation.rb +45 -27
  170. data/lib/active_record/relation/finder_methods.rb +75 -76
  171. data/lib/active_record/relation/from_clause.rb +2 -8
  172. data/lib/active_record/relation/merger.rb +53 -23
  173. data/lib/active_record/relation/predicate_builder.rb +60 -79
  174. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  175. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  176. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  177. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  178. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  179. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  180. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  181. data/lib/active_record/relation/query_attribute.rb +28 -2
  182. data/lib/active_record/relation/query_methods.rb +128 -99
  183. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  184. data/lib/active_record/relation/spawn_methods.rb +4 -2
  185. data/lib/active_record/relation/where_clause.rb +65 -68
  186. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  187. data/lib/active_record/result.rb +2 -0
  188. data/lib/active_record/runtime_registry.rb +2 -0
  189. data/lib/active_record/sanitization.rb +129 -121
  190. data/lib/active_record/schema.rb +4 -2
  191. data/lib/active_record/schema_dumper.rb +36 -26
  192. data/lib/active_record/schema_migration.rb +2 -0
  193. data/lib/active_record/scoping.rb +9 -8
  194. data/lib/active_record/scoping/default.rb +8 -9
  195. data/lib/active_record/scoping/named.rb +23 -7
  196. data/lib/active_record/secure_token.rb +2 -0
  197. data/lib/active_record/serialization.rb +2 -0
  198. data/lib/active_record/statement_cache.rb +23 -13
  199. data/lib/active_record/store.rb +3 -1
  200. data/lib/active_record/suppressor.rb +2 -0
  201. data/lib/active_record/table_metadata.rb +12 -3
  202. data/lib/active_record/tasks/database_tasks.rb +25 -14
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  206. data/lib/active_record/timestamp.rb +6 -6
  207. data/lib/active_record/touch_later.rb +2 -0
  208. data/lib/active_record/transactions.rb +33 -28
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type.rb +4 -1
  211. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  212. data/lib/active_record/type/date.rb +2 -0
  213. data/lib/active_record/type/date_time.rb +2 -0
  214. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  215. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  216. data/lib/active_record/type/internal/timezone.rb +2 -0
  217. data/lib/active_record/type/json.rb +30 -0
  218. data/lib/active_record/type/serialized.rb +2 -0
  219. data/lib/active_record/type/text.rb +2 -0
  220. data/lib/active_record/type/time.rb +2 -0
  221. data/lib/active_record/type/type_map.rb +2 -0
  222. data/lib/active_record/type/unsigned_integer.rb +2 -0
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/type_caster/connection.rb +2 -0
  225. data/lib/active_record/type_caster/map.rb +3 -1
  226. data/lib/active_record/validations.rb +2 -0
  227. data/lib/active_record/validations/absence.rb +2 -0
  228. data/lib/active_record/validations/associated.rb +2 -0
  229. data/lib/active_record/validations/length.rb +2 -0
  230. data/lib/active_record/validations/presence.rb +2 -0
  231. data/lib/active_record/validations/uniqueness.rb +35 -5
  232. data/lib/active_record/version.rb +2 -0
  233. data/lib/rails/generators/active_record.rb +3 -1
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration.rb +2 -0
  237. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  238. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  239. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  241. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  243. metadata +23 -36
  244. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  245. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  246. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  248. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  249. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  250. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -122
  254. data/lib/active_record/attribute_set.rb +0 -113
  255. data/lib/active_record/attribute_set/builder.rb +0 -126
  256. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  257. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  258. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  259. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  260. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  261. data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2017 David Heinemeier Hansson
1
+ Copyright (c) 2004-2018 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,7 +26,7 @@ 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 NOT NULL auto_increment,
29
+ id bigint NOT NULL auto_increment,
30
30
  name varchar(255),
31
31
  PRIMARY KEY (id)
32
32
  );
@@ -162,7 +162,7 @@ This would also define the following accessors: Product#name and
162
162
  == Philosophy
163
163
 
164
164
  Active Record is an implementation of the object-relational mapping (ORM)
165
- pattern[http://www.martinfowler.com/eaaCatalog/activeRecord.html] by the same
165
+ pattern[https://www.martinfowler.com/eaaCatalog/activeRecord.html] by the same
166
166
  name described by Martin Fowler:
167
167
 
168
168
  "An object that wraps a row in a database table or view,
@@ -192,14 +192,14 @@ The latest version of Active Record can be installed with RubyGems:
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/master/activerecord
195
+ * https://github.com/rails/rails/tree/5-2-stable/activerecord
196
196
 
197
197
 
198
198
  == License
199
199
 
200
200
  Active Record is released under the MIT license:
201
201
 
202
- * http://www.opensource.org/licenses/MIT
202
+ * https://opensource.org/licenses/MIT
203
203
 
204
204
 
205
205
  == Support
@@ -208,7 +208,7 @@ API documentation is at:
208
208
 
209
209
  * http://api.rubyonrails.org
210
210
 
211
- Bug reports can be filed for the Ruby on Rails project here:
211
+ Bug reports for the Ruby on Rails project can be filed here:
212
212
 
213
213
  * https://github.com/rails/rails/issues
214
214
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record"
2
4
  require "benchmark/ips"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record"
2
4
 
3
5
  class Person < ActiveRecord::Base
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
- # Copyright (c) 2004-2017 David Heinemeier Hansson
4
+ # Copyright (c) 2004-2018 David Heinemeier Hansson
3
5
  #
4
6
  # Permission is hereby granted, free of charge, to any person obtaining
5
7
  # a copy of this software and associated documentation files (the
@@ -25,14 +27,14 @@ require "active_support"
25
27
  require "active_support/rails"
26
28
  require "active_model"
27
29
  require "arel"
30
+ require "yaml"
28
31
 
29
32
  require "active_record/version"
30
- require "active_record/attribute_set"
33
+ require "active_model/attribute_set"
31
34
 
32
35
  module ActiveRecord
33
36
  extend ActiveSupport::Autoload
34
37
 
35
- autoload :Attribute
36
38
  autoload :Base
37
39
  autoload :Callbacks
38
40
  autoload :Core
@@ -102,6 +104,7 @@ module ActiveRecord
102
104
 
103
105
  autoload :Result
104
106
  autoload :TableMetadata
107
+ autoload :Type
105
108
  end
106
109
 
107
110
  module Coders
@@ -177,5 +180,9 @@ ActiveSupport.on_load(:active_record) do
177
180
  end
178
181
 
179
182
  ActiveSupport.on_load(:i18n) do
180
- I18n.load_path << File.dirname(__FILE__) + "/active_record/locale/en.yml"
183
+ I18n.load_path << File.expand_path("active_record/locale/en.yml", __dir__)
181
184
  end
185
+
186
+ YAML.load_tags["!ruby/object:ActiveRecord::AttributeSet"] = "ActiveModel::AttributeSet"
187
+ YAML.load_tags["!ruby/object:ActiveRecord::Attribute::FromDatabase"] = "ActiveModel::Attribute::FromDatabase"
188
+ YAML.load_tags["!ruby/object:ActiveRecord::LazyAttributeHash"] = "ActiveModel::LazyAttributeHash"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # See ActiveRecord::Aggregations::ClassMethods for documentation
3
5
  module Aggregations
@@ -33,7 +35,7 @@ module ActiveRecord
33
35
  # the database).
34
36
  #
35
37
  # class Customer < ActiveRecord::Base
36
- # composed_of :balance, class_name: "Money", mapping: %w(amount currency)
38
+ # composed_of :balance, class_name: "Money", mapping: %w(balance amount)
37
39
  # composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
38
40
  # end
39
41
  #
@@ -175,9 +177,9 @@ module ActiveRecord
175
177
  #
176
178
  # Once a #composed_of relationship is specified for a model, records can be loaded from the database
177
179
  # by specifying an instance of the value object in the conditions hash. The following example
178
- # finds all customers with +balance_amount+ equal to 20 and +balance_currency+ equal to "USD":
180
+ # finds all customers with +address_street+ equal to "May Street" and +address_city+ equal to "Chicago":
179
181
  #
180
- # Customer.where(balance: Money.new(20, "USD"))
182
+ # Customer.where(address: Address.new("May Street", "Chicago"))
181
183
  #
182
184
  module ClassMethods
183
185
  # Adds reader and writer methods for manipulating a value object:
@@ -210,8 +212,7 @@ module ActiveRecord
210
212
  #
211
213
  # Option examples:
212
214
  # composed_of :temperature, mapping: %w(reading celsius)
213
- # composed_of :balance, class_name: "Money", mapping: %w(balance amount),
214
- # converter: Proc.new { |balance| balance.to_money }
215
+ # composed_of :balance, class_name: "Money", mapping: %w(balance amount)
215
216
  # composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
216
217
  # composed_of :gps_location
217
218
  # composed_of :gps_location, allow_nil: true
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class AssociationRelation < Relation
3
- def initialize(klass, table, predicate_builder, association)
4
- super(klass, table, predicate_builder)
5
+ def initialize(klass, association)
6
+ super(klass)
5
7
  @association = association
6
8
  end
7
9
 
@@ -29,9 +31,9 @@ module ActiveRecord
29
31
  private
30
32
 
31
33
  def exec_queries
32
- super do |r|
33
- @association.set_inverse_instance r
34
- yield r if block_given?
34
+ super do |record|
35
+ @association.set_inverse_instance_from_queries(record)
36
+ yield record if block_given?
35
37
  end
36
38
  end
37
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/enumerable"
2
4
  require "active_support/core_ext/string/conversions"
3
5
  require "active_support/core_ext/module/remove_method"
@@ -138,26 +140,6 @@ module ActiveRecord
138
140
  class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
139
141
  end
140
142
 
141
- class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc:
142
- def initialize(owner = nil, reflection = nil)
143
- if owner && reflection
144
- 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.")
145
- else
146
- super("Cannot associate new records.")
147
- end
148
- end
149
- end
150
-
151
- class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc:
152
- def initialize(owner = nil, reflection = nil)
153
- if owner && reflection
154
- 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.")
155
- else
156
- super("Cannot dissociate new records.")
157
- end
158
- end
159
- end
160
-
161
143
  class ThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
162
144
  def initialize(owner = nil, reflection = nil)
163
145
  if owner && reflection
@@ -187,16 +169,6 @@ module ActiveRecord
187
169
  end
188
170
  end
189
171
 
190
- class ReadOnlyAssociation < ActiveRecordError #:nodoc:
191
- def initialize(reflection = nil)
192
- if reflection
193
- super("Cannot add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.")
194
- else
195
- super("Read-only reflection error.")
196
- end
197
- end
198
- end
199
-
200
172
  # This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
201
173
  # (has_many, has_one) when there is at least 1 child associated instance.
202
174
  # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
@@ -269,7 +241,7 @@ module ActiveRecord
269
241
  association
270
242
  end
271
243
 
272
- def association_cached?(name) # :nodoc
244
+ def association_cached?(name) # :nodoc:
273
245
  @association_cache.key?(name)
274
246
  end
275
247
 
@@ -481,14 +453,14 @@ module ActiveRecord
481
453
  # The tables for these classes could look something like:
482
454
  #
483
455
  # CREATE TABLE users (
484
- # id int NOT NULL auto_increment,
485
- # account_id int default NULL,
456
+ # id bigint NOT NULL auto_increment,
457
+ # account_id bigint default NULL,
486
458
  # name varchar default NULL,
487
459
  # PRIMARY KEY (id)
488
460
  # )
489
461
  #
490
462
  # CREATE TABLE accounts (
491
- # id int NOT NULL auto_increment,
463
+ # id bigint NOT NULL auto_increment,
492
464
  # name varchar default NULL,
493
465
  # PRIMARY KEY (id)
494
466
  # )
@@ -555,9 +527,8 @@ module ActiveRecord
555
527
  # has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
556
528
  # end
557
529
  #
558
- # Note: Joining, eager loading and preloading of these associations is not fully possible.
530
+ # Note: Joining, eager loading and preloading of these associations is not possible.
559
531
  # These operations happen before instance creation and the scope will be called with a +nil+ argument.
560
- # This can lead to unexpected behavior and is deprecated.
561
532
  #
562
533
  # == Association callbacks
563
534
  #
@@ -848,7 +819,7 @@ module ActiveRecord
848
819
  # project.milestones # fetches milestones from the database
849
820
  # project.milestones.size # uses the milestone cache
850
821
  # project.milestones.empty? # uses the milestone cache
851
- # project.milestones(true).size # fetches milestones from the database
822
+ # project.milestones.reload.size # fetches milestones from the database
852
823
  # project.milestones # uses the milestone cache
853
824
  #
854
825
  # == Eager loading of associations
@@ -1090,12 +1061,6 @@ module ActiveRecord
1090
1061
  # belongs_to :dungeon, inverse_of: :evil_wizard
1091
1062
  # end
1092
1063
  #
1093
- # There are limitations to <tt>:inverse_of</tt> support:
1094
- #
1095
- # * does not work with <tt>:through</tt> associations.
1096
- # * does not work with <tt>:polymorphic</tt> associations.
1097
- # * inverse associations for #belongs_to associations #has_many are ignored.
1098
- #
1099
1064
  # For more information, see the documentation for the +:inverse_of+ option.
1100
1065
  #
1101
1066
  # == Deleting from associations
@@ -1189,7 +1154,7 @@ module ActiveRecord
1189
1154
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1190
1155
  # <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
1191
1156
  #
1192
- # [collection(force_reload = false)]
1157
+ # [collection]
1193
1158
  # Returns a Relation of all the associated objects.
1194
1159
  # An empty Relation is returned if none are found.
1195
1160
  # [collection<<(object, ...)]
@@ -1267,9 +1232,9 @@ module ActiveRecord
1267
1232
  # * <tt>Firm#clients.size</tt> (similar to <tt>Client.count "firm_id = #{id}"</tt>)
1268
1233
  # * <tt>Firm#clients.find</tt> (similar to <tt>Client.where(firm_id: id).find(id)</tt>)
1269
1234
  # * <tt>Firm#clients.exists?(name: 'ACME')</tt> (similar to <tt>Client.exists?(name: 'ACME', firm_id: firm.id)</tt>)
1270
- # * <tt>Firm#clients.build</tt> (similar to <tt>Client.new("firm_id" => id)</tt>)
1271
- # * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save; c</tt>)
1272
- # * <tt>Firm#clients.create!</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save!</tt>)
1235
+ # * <tt>Firm#clients.build</tt> (similar to <tt>Client.new(firm_id: id)</tt>)
1236
+ # * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new(firm_id: id); c.save; c</tt>)
1237
+ # * <tt>Firm#clients.create!</tt> (similar to <tt>c = Client.new(firm_id: id); c.save!</tt>)
1273
1238
  # * <tt>Firm#clients.reload</tt>
1274
1239
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1275
1240
  #
@@ -1308,6 +1273,9 @@ module ActiveRecord
1308
1273
  # Specify the foreign key used for the association. By default this is guessed to be the name
1309
1274
  # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
1310
1275
  # association will use "person_id" as the default <tt>:foreign_key</tt>.
1276
+ #
1277
+ # If you are going to modify the association (rather than just read from it), then it is
1278
+ # a good idea to set the <tt>:inverse_of</tt> option.
1311
1279
  # [:foreign_type]
1312
1280
  # Specify the column used to store the associated object's type, if this is a polymorphic
1313
1281
  # association. By default this is guessed to be the name of the polymorphic association
@@ -1381,8 +1349,7 @@ module ActiveRecord
1381
1349
  # <tt>:autosave</tt> to <tt>true</tt>.
1382
1350
  # [:inverse_of]
1383
1351
  # Specifies the name of the #belongs_to association on the associated object
1384
- # that is the inverse of this #has_many association. Does not work in combination
1385
- # with <tt>:through</tt> or <tt>:as</tt> options.
1352
+ # that is the inverse of this #has_many association.
1386
1353
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1387
1354
  # [:extend]
1388
1355
  # Specifies a module or array of modules that will be extended into the association object returned.
@@ -1398,7 +1365,7 @@ module ActiveRecord
1398
1365
  # has_many :tags, as: :taggable
1399
1366
  # has_many :reports, -> { readonly }
1400
1367
  # has_many :subscribers, through: :subscriptions, source: :user
1401
- def has_many(name, scope = nil, options = {}, &extension)
1368
+ def has_many(name, scope = nil, **options, &extension)
1402
1369
  reflection = Builder::HasMany.build(self, name, scope, options, &extension)
1403
1370
  Reflection.add_reflection self, name, reflection
1404
1371
  end
@@ -1438,9 +1405,9 @@ module ActiveRecord
1438
1405
  # An Account class declares <tt>has_one :beneficiary</tt>, which will add:
1439
1406
  # * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.where(account_id: id).first</tt>)
1440
1407
  # * <tt>Account#beneficiary=(beneficiary)</tt> (similar to <tt>beneficiary.account_id = account.id; beneficiary.save</tt>)
1441
- # * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new("account_id" => id)</tt>)
1442
- # * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save; b</tt>)
1443
- # * <tt>Account#create_beneficiary!</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save!; b</tt>)
1408
+ # * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new(account_id: id)</tt>)
1409
+ # * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new(account_id: id); b.save; b</tt>)
1410
+ # * <tt>Account#create_beneficiary!</tt> (similar to <tt>b = Beneficiary.new(account_id: id); b.save!; b</tt>)
1444
1411
  # * <tt>Account#reload_beneficiary</tt>
1445
1412
  #
1446
1413
  # === Scopes
@@ -1478,6 +1445,9 @@ module ActiveRecord
1478
1445
  # Specify the foreign key used for the association. By default this is guessed to be the name
1479
1446
  # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
1480
1447
  # will use "person_id" as the default <tt>:foreign_key</tt>.
1448
+ #
1449
+ # If you are going to modify the association (rather than just read from it), then it is
1450
+ # a good idea to set the <tt>:inverse_of</tt> option.
1481
1451
  # [:foreign_type]
1482
1452
  # Specify the column used to store the associated object's type, if this is a polymorphic
1483
1453
  # association. By default this is guessed to be the name of the polymorphic association
@@ -1493,6 +1463,9 @@ module ActiveRecord
1493
1463
  # <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
1494
1464
  # source reflection. You can only use a <tt>:through</tt> query through a #has_one
1495
1465
  # or #belongs_to association on the join model.
1466
+ #
1467
+ # If you are going to modify the association (rather than just read from it), then it is
1468
+ # a good idea to set the <tt>:inverse_of</tt> option.
1496
1469
  # [:source]
1497
1470
  # Specifies the source association name used by #has_one <tt>:through</tt> queries.
1498
1471
  # Only use it if the name cannot be inferred from the association.
@@ -1513,8 +1486,7 @@ module ActiveRecord
1513
1486
  # <tt>:autosave</tt> to <tt>true</tt>.
1514
1487
  # [:inverse_of]
1515
1488
  # Specifies the name of the #belongs_to association on the associated object
1516
- # that is the inverse of this #has_one association. Does not work in combination
1517
- # with <tt>:through</tt> or <tt>:as</tt> options.
1489
+ # that is the inverse of this #has_one association.
1518
1490
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1519
1491
  # [:required]
1520
1492
  # When set to +true+, the association will also have its presence validated.
@@ -1532,7 +1504,7 @@ module ActiveRecord
1532
1504
  # has_one :club, through: :membership
1533
1505
  # has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
1534
1506
  # has_one :credit_card, required: true
1535
- def has_one(name, scope = nil, options = {})
1507
+ def has_one(name, scope = nil, **options)
1536
1508
  reflection = Builder::HasOne.build(self, name, scope, options)
1537
1509
  Reflection.add_reflection self, name, reflection
1538
1510
  end
@@ -1599,6 +1571,9 @@ module ActiveRecord
1599
1571
  # association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
1600
1572
  # <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
1601
1573
  # of "favorite_person_id".
1574
+ #
1575
+ # If you are going to modify the association (rather than just read from it), then it is
1576
+ # a good idea to set the <tt>:inverse_of</tt> option.
1602
1577
  # [:foreign_type]
1603
1578
  # Specify the column used to store the associated object's type, if this is a polymorphic
1604
1579
  # association. By default this is guessed to be the name of the association with a "_type"
@@ -1648,8 +1623,7 @@ module ActiveRecord
1648
1623
  # +after_commit+ and +after_rollback+ callbacks are executed.
1649
1624
  # [:inverse_of]
1650
1625
  # Specifies the name of the #has_one or #has_many association on the associated
1651
- # object that is the inverse of this #belongs_to association. Does not work in
1652
- # combination with the <tt>:polymorphic</tt> options.
1626
+ # object that is the inverse of this #belongs_to association.
1653
1627
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1654
1628
  # [:optional]
1655
1629
  # When set to +true+, the association will not have its presence validated.
@@ -1676,7 +1650,7 @@ module ActiveRecord
1676
1650
  # belongs_to :company, touch: :employees_last_updated_at
1677
1651
  # belongs_to :user, optional: true
1678
1652
  # belongs_to :account, default: -> { company.account }
1679
- def belongs_to(name, scope = nil, options = {})
1653
+ def belongs_to(name, scope = nil, **options)
1680
1654
  reflection = Builder::BelongsTo.build(self, name, scope, options)
1681
1655
  Reflection.add_reflection self, name, reflection
1682
1656
  end
@@ -1772,8 +1746,8 @@ module ActiveRecord
1772
1746
  # * <tt>Developer#projects.size</tt>
1773
1747
  # * <tt>Developer#projects.find(id)</tt>
1774
1748
  # * <tt>Developer#projects.exists?(...)</tt>
1775
- # * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("developer_id" => id)</tt>)
1776
- # * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("developer_id" => id); c.save; c</tt>)
1749
+ # * <tt>Developer#projects.build</tt> (similar to <tt>Project.new(developer_id: id)</tt>)
1750
+ # * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new(developer_id: id); c.save; c</tt>)
1777
1751
  # * <tt>Developer#projects.reload</tt>
1778
1752
  # The declaration may include an +options+ hash to specialize the behavior of the association.
1779
1753
  #
@@ -1818,6 +1792,9 @@ module ActiveRecord
1818
1792
  # of this class in lower-case and "_id" suffixed. So a Person class that makes
1819
1793
  # a #has_and_belongs_to_many association to Project will use "person_id" as the
1820
1794
  # default <tt>:foreign_key</tt>.
1795
+ #
1796
+ # If you are going to modify the association (rather than just read from it), then it is
1797
+ # a good idea to set the <tt>:inverse_of</tt> option.
1821
1798
  # [:association_foreign_key]
1822
1799
  # Specify the foreign key used for the association on the receiving side of the association.
1823
1800
  # By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
@@ -1846,7 +1823,7 @@ module ActiveRecord
1846
1823
 
1847
1824
  builder = Builder::HasAndBelongsToMany.new name, self, options
1848
1825
 
1849
- join_model = ActiveSupport::Deprecation.silence { builder.through_model }
1826
+ join_model = builder.through_model
1850
1827
 
1851
1828
  const_set join_model.name, join_model
1852
1829
  private_constant join_model.name
@@ -1875,7 +1852,7 @@ module ActiveRecord
1875
1852
  hm_options[k] = options[k] if options.key? k
1876
1853
  end
1877
1854
 
1878
- ActiveSupport::Deprecation.silence { has_many name, scope, hm_options, &extension }
1855
+ has_many name, scope, hm_options, &extension
1879
1856
  _reflections[name.to_s].parent_reflection = habtm_reflection
1880
1857
  end
1881
1858
  end
@@ -1,51 +1,41 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/string/conversions"
2
4
 
3
5
  module ActiveRecord
4
6
  module Associations
5
7
  # Keeps track of table aliases for ActiveRecord::Associations::JoinDependency
6
8
  class AliasTracker # :nodoc:
7
- attr_reader :aliases
8
-
9
- def self.create(connection, initial_table)
10
- aliases = Hash.new(0)
11
- aliases[initial_table] = 1
12
- new(connection, aliases)
13
- end
14
-
15
- def self.create_with_joins(connection, initial_table, joins)
9
+ def self.create(connection, initial_table, joins)
16
10
  if joins.empty?
17
- create(connection, initial_table)
11
+ aliases = Hash.new(0)
18
12
  else
19
13
  aliases = Hash.new { |h, k|
20
14
  h[k] = initial_count_for(connection, k, joins)
21
15
  }
22
- aliases[initial_table] = 1
23
- new(connection, aliases)
24
16
  end
17
+ aliases[initial_table] = 1
18
+ new(connection, aliases)
25
19
  end
26
20
 
27
21
  def self.initial_count_for(connection, name, table_joins)
28
- # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase
29
- quoted_name = connection.quote_table_name(name).downcase
22
+ quoted_name = nil
30
23
 
31
24
  counts = table_joins.map do |join|
32
25
  if join.is_a?(Arel::Nodes::StringJoin)
26
+ # quoted_name should be case ignored as some database adapters (Oracle) return quoted name in uppercase
27
+ quoted_name ||= connection.quote_table_name(name)
28
+
33
29
  # Table names + table aliases
34
- join.left.downcase.scan(
35
- /join(?:\s+\w+)?\s+(\S+\s+)?#{quoted_name}\son/
30
+ join.left.scan(
31
+ /JOIN(?:\s+\w+)?\s+(?:\S+\s+)?(?:#{quoted_name}|#{name})\sON/i
36
32
  ).size
37
- elsif join.respond_to? :left
38
- join.left.table_name == name ? 1 : 0
33
+ elsif join.is_a?(Arel::Nodes::Join)
34
+ join.left.name == name ? 1 : 0
35
+ elsif join.is_a?(Hash)
36
+ join[name]
39
37
  else
40
- # this branch is reached by two tests:
41
- #
42
- # activerecord/test/cases/associations/cascaded_eager_loading_test.rb:37
43
- # with :posts
44
- #
45
- # activerecord/test/cases/associations/eager_test.rb:1133
46
- # with :comments
47
- #
48
- 0
38
+ raise ArgumentError, "joins list should be initialized by list of Arel::Nodes::Join"
49
39
  end
50
40
  end
51
41
 
@@ -79,6 +69,8 @@ module ActiveRecord
79
69
  end
80
70
  end
81
71
 
72
+ attr_reader :aliases
73
+
82
74
  private
83
75
 
84
76
  def truncate(name)