activerecord 6.0.0.beta1 → 6.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 (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +455 -9
  3. data/README.rdoc +3 -1
  4. data/lib/active_record/associations/association.rb +18 -1
  5. data/lib/active_record/associations/builder/association.rb +14 -18
  6. data/lib/active_record/associations/builder/belongs_to.rb +5 -2
  7. data/lib/active_record/associations/builder/collection_association.rb +5 -15
  8. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -1
  9. data/lib/active_record/associations/builder/has_many.rb +2 -0
  10. data/lib/active_record/associations/builder/has_one.rb +35 -1
  11. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  12. data/lib/active_record/associations/collection_association.rb +5 -6
  13. data/lib/active_record/associations/collection_proxy.rb +13 -42
  14. data/lib/active_record/associations/has_many_association.rb +1 -9
  15. data/lib/active_record/associations/has_many_through_association.rb +4 -11
  16. data/lib/active_record/associations/join_dependency/join_association.rb +21 -7
  17. data/lib/active_record/associations/join_dependency.rb +10 -9
  18. data/lib/active_record/associations/preloader/association.rb +37 -34
  19. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  20. data/lib/active_record/associations/preloader.rb +11 -6
  21. data/lib/active_record/associations.rb +3 -2
  22. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
  23. data/lib/active_record/attribute_methods/dirty.rb +47 -14
  24. data/lib/active_record/attribute_methods/primary_key.rb +7 -15
  25. data/lib/active_record/attribute_methods/query.rb +2 -3
  26. data/lib/active_record/attribute_methods/read.rb +3 -9
  27. data/lib/active_record/attribute_methods/write.rb +6 -12
  28. data/lib/active_record/attribute_methods.rb +3 -53
  29. data/lib/active_record/attributes.rb +13 -0
  30. data/lib/active_record/autosave_association.rb +15 -5
  31. data/lib/active_record/base.rb +0 -1
  32. data/lib/active_record/callbacks.rb +3 -3
  33. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +124 -23
  34. data/lib/active_record/connection_adapters/abstract/database_limits.rb +8 -4
  35. data/lib/active_record/connection_adapters/abstract/database_statements.rb +101 -70
  36. data/lib/active_record/connection_adapters/abstract/query_cache.rb +11 -5
  37. data/lib/active_record/connection_adapters/abstract/quoting.rb +63 -6
  38. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +5 -2
  39. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +51 -40
  40. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
  41. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +95 -30
  42. data/lib/active_record/connection_adapters/abstract/transaction.rb +17 -6
  43. data/lib/active_record/connection_adapters/abstract_adapter.rb +108 -39
  44. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +93 -134
  45. data/lib/active_record/connection_adapters/column.rb +17 -13
  46. data/lib/active_record/connection_adapters/connection_specification.rb +1 -1
  47. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +3 -3
  48. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -7
  49. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  50. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  51. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  52. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +66 -5
  53. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  54. data/lib/active_record/connection_adapters/mysql2_adapter.rb +18 -5
  55. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -30
  56. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +5 -1
  57. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  58. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  59. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
  60. data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -3
  61. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +36 -0
  62. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +98 -89
  63. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +47 -63
  64. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +23 -27
  65. data/lib/active_record/connection_adapters/postgresql_adapter.rb +91 -24
  66. data/lib/active_record/connection_adapters/schema_cache.rb +32 -14
  67. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  68. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  69. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -2
  70. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +28 -2
  71. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +69 -118
  72. data/lib/active_record/connection_handling.rb +32 -16
  73. data/lib/active_record/core.rb +27 -20
  74. data/lib/active_record/database_configurations/hash_config.rb +11 -11
  75. data/lib/active_record/database_configurations/url_config.rb +21 -16
  76. data/lib/active_record/database_configurations.rb +99 -50
  77. data/lib/active_record/dynamic_matchers.rb +1 -1
  78. data/lib/active_record/enum.rb +15 -0
  79. data/lib/active_record/errors.rb +18 -13
  80. data/lib/active_record/fixtures.rb +11 -6
  81. data/lib/active_record/gem_version.rb +1 -1
  82. data/lib/active_record/inheritance.rb +1 -1
  83. data/lib/active_record/insert_all.rb +179 -0
  84. data/lib/active_record/integration.rb +13 -1
  85. data/lib/active_record/internal_metadata.rb +5 -1
  86. data/lib/active_record/locking/optimistic.rb +3 -4
  87. data/lib/active_record/log_subscriber.rb +1 -1
  88. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  89. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  90. data/lib/active_record/middleware/database_selector.rb +75 -0
  91. data/lib/active_record/migration/command_recorder.rb +28 -14
  92. data/lib/active_record/migration/compatibility.rb +72 -63
  93. data/lib/active_record/migration.rb +62 -44
  94. data/lib/active_record/persistence.rb +212 -19
  95. data/lib/active_record/querying.rb +18 -14
  96. data/lib/active_record/railtie.rb +9 -1
  97. data/lib/active_record/railties/collection_cache_association_loading.rb +3 -3
  98. data/lib/active_record/railties/databases.rake +124 -25
  99. data/lib/active_record/reflection.rb +18 -32
  100. data/lib/active_record/relation/calculations.rb +40 -44
  101. data/lib/active_record/relation/delegation.rb +23 -31
  102. data/lib/active_record/relation/finder_methods.rb +13 -13
  103. data/lib/active_record/relation/merger.rb +11 -16
  104. data/lib/active_record/relation/query_attribute.rb +5 -3
  105. data/lib/active_record/relation/query_methods.rb +217 -68
  106. data/lib/active_record/relation/spawn_methods.rb +1 -1
  107. data/lib/active_record/relation/where_clause.rb +10 -10
  108. data/lib/active_record/relation.rb +184 -35
  109. data/lib/active_record/sanitization.rb +33 -4
  110. data/lib/active_record/schema.rb +1 -1
  111. data/lib/active_record/schema_dumper.rb +10 -1
  112. data/lib/active_record/schema_migration.rb +1 -1
  113. data/lib/active_record/scoping/default.rb +7 -15
  114. data/lib/active_record/scoping/named.rb +10 -2
  115. data/lib/active_record/scoping.rb +6 -7
  116. data/lib/active_record/statement_cache.rb +2 -2
  117. data/lib/active_record/store.rb +48 -0
  118. data/lib/active_record/table_metadata.rb +9 -13
  119. data/lib/active_record/tasks/database_tasks.rb +109 -6
  120. data/lib/active_record/tasks/mysql_database_tasks.rb +3 -1
  121. data/lib/active_record/test_databases.rb +1 -16
  122. data/lib/active_record/test_fixtures.rb +2 -2
  123. data/lib/active_record/timestamp.rb +35 -19
  124. data/lib/active_record/touch_later.rb +4 -2
  125. data/lib/active_record/transactions.rb +55 -45
  126. data/lib/active_record/type_caster/connection.rb +16 -10
  127. data/lib/active_record/validations/uniqueness.rb +4 -4
  128. data/lib/active_record/validations.rb +1 -0
  129. data/lib/active_record.rb +7 -1
  130. data/lib/arel/insert_manager.rb +3 -3
  131. data/lib/arel/nodes/and.rb +1 -1
  132. data/lib/arel/nodes/case.rb +1 -1
  133. data/lib/arel/nodes/comment.rb +29 -0
  134. data/lib/arel/nodes/select_core.rb +16 -12
  135. data/lib/arel/nodes/unary.rb +1 -0
  136. data/lib/arel/nodes/values_list.rb +2 -17
  137. data/lib/arel/nodes.rb +2 -1
  138. data/lib/arel/select_manager.rb +10 -10
  139. data/lib/arel/visitors/depth_first.rb +7 -2
  140. data/lib/arel/visitors/dot.rb +7 -2
  141. data/lib/arel/visitors/ibm_db.rb +13 -0
  142. data/lib/arel/visitors/informix.rb +6 -0
  143. data/lib/arel/visitors/mssql.rb +15 -1
  144. data/lib/arel/visitors/oracle12.rb +4 -5
  145. data/lib/arel/visitors/postgresql.rb +4 -10
  146. data/lib/arel/visitors/to_sql.rb +107 -131
  147. data/lib/arel/visitors/visitor.rb +9 -5
  148. data/lib/arel.rb +7 -0
  149. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
  150. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  151. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  152. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  153. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  154. metadata +17 -13
  155. data/lib/active_record/collection_cache_key.rb +0 -53
  156. data/lib/arel/nodes/values.rb +0 -16
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "mutex_m"
4
+
3
5
  module ActiveRecord
4
6
  module Delegation # :nodoc:
5
7
  module DelegateCache # :nodoc:
@@ -31,6 +33,10 @@ module ActiveRecord
31
33
  super
32
34
  end
33
35
 
36
+ def generate_relation_method(method)
37
+ generated_relation_methods.generate_method(method)
38
+ end
39
+
34
40
  protected
35
41
  def include_relation_methods(delegate)
36
42
  superclass.include_relation_methods(delegate) unless base_class?
@@ -39,27 +45,35 @@ module ActiveRecord
39
45
 
40
46
  private
41
47
  def generated_relation_methods
42
- @generated_relation_methods ||= Module.new.tap do |mod|
43
- mod_name = "GeneratedRelationMethods"
44
- const_set mod_name, mod
45
- private_constant mod_name
48
+ @generated_relation_methods ||= GeneratedRelationMethods.new.tap do |mod|
49
+ const_set(:GeneratedRelationMethods, mod)
50
+ private_constant :GeneratedRelationMethods
46
51
  end
47
52
  end
53
+ end
54
+
55
+ class GeneratedRelationMethods < Module # :nodoc:
56
+ include Mutex_m
57
+
58
+ def generate_method(method)
59
+ synchronize do
60
+ return if method_defined?(method)
48
61
 
49
- def generate_relation_method(method)
50
62
  if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method)
51
- generated_relation_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
63
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
52
64
  def #{method}(*args, &block)
53
65
  scoping { klass.#{method}(*args, &block) }
54
66
  end
55
67
  RUBY
56
68
  else
57
- generated_relation_methods.define_method(method) do |*args, &block|
69
+ define_method(method) do |*args, &block|
58
70
  scoping { klass.public_send(method, *args, &block) }
59
71
  end
60
72
  end
61
73
  end
74
+ end
62
75
  end
76
+ private_constant :GeneratedRelationMethods
63
77
 
64
78
  extend ActiveSupport::Concern
65
79
 
@@ -78,39 +92,17 @@ module ActiveRecord
78
92
  module ClassSpecificRelation # :nodoc:
79
93
  extend ActiveSupport::Concern
80
94
 
81
- included do
82
- @delegation_mutex = Mutex.new
83
- end
84
-
85
95
  module ClassMethods # :nodoc:
86
96
  def name
87
97
  superclass.name
88
98
  end
89
-
90
- def delegate_to_scoped_klass(method)
91
- @delegation_mutex.synchronize do
92
- return if method_defined?(method)
93
-
94
- if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method)
95
- module_eval <<-RUBY, __FILE__, __LINE__ + 1
96
- def #{method}(*args, &block)
97
- scoping { @klass.#{method}(*args, &block) }
98
- end
99
- RUBY
100
- else
101
- define_method method do |*args, &block|
102
- scoping { @klass.public_send(method, *args, &block) }
103
- end
104
- end
105
- end
106
- end
107
99
  end
108
100
 
109
101
  private
110
102
 
111
103
  def method_missing(method, *args, &block)
112
104
  if @klass.respond_to?(method)
113
- self.class.delegate_to_scoped_klass(method)
105
+ @klass.generate_relation_method(method)
114
106
  scoping { @klass.public_send(method, *args, &block) }
115
107
  else
116
108
  super
@@ -132,7 +124,7 @@ module ActiveRecord
132
124
 
133
125
  private
134
126
  def respond_to_missing?(method, _)
135
- super || @klass.respond_to?(method) || arel.respond_to?(method)
127
+ super || @klass.respond_to?(method)
136
128
  end
137
129
  end
138
130
  end
@@ -7,8 +7,8 @@ module ActiveRecord
7
7
  ONE_AS_ONE = "1 AS one"
8
8
 
9
9
  # Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
10
- # If one or more records can not be found for the requested ids, then RecordNotFound will be raised. If the primary key
11
- # is an integer, find by id coerces its arguments using +to_i+.
10
+ # If one or more records cannot be found for the requested ids, then ActiveRecord::RecordNotFound will be raised.
11
+ # If the primary key is an integer, find by id coerces its arguments by using +to_i+.
12
12
  #
13
13
  # Person.find(1) # returns the object for ID = 1
14
14
  # Person.find("1") # returns the object for ID = 1
@@ -307,8 +307,6 @@ module ActiveRecord
307
307
 
308
308
  return false if !conditions || limit_value == 0
309
309
 
310
- conditions = sanitize_forbidden_attributes(conditions)
311
-
312
310
  if eager_loading?
313
311
  relation = apply_join_dependency(eager_loading: false)
314
312
  return relation.exists?(conditions)
@@ -316,7 +314,7 @@ module ActiveRecord
316
314
 
317
315
  relation = construct_relation_for_exists(conditions)
318
316
 
319
- skip_query_cache_if_necessary { connection.select_value(relation.arel, "#{name} Exists") } ? true : false
317
+ skip_query_cache_if_necessary { connection.select_one(relation.arel, "#{name} Exists?") } ? true : false
320
318
  end
321
319
 
322
320
  # This method is called whenever no records are found with either a single
@@ -354,7 +352,13 @@ module ActiveRecord
354
352
  end
355
353
 
356
354
  def construct_relation_for_exists(conditions)
357
- relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
355
+ conditions = sanitize_forbidden_attributes(conditions)
356
+
357
+ if distinct_value && offset_value
358
+ relation = except(:order).limit!(1)
359
+ else
360
+ relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
361
+ end
358
362
 
359
363
  case conditions
360
364
  when Array, Hash
@@ -366,14 +370,10 @@ module ActiveRecord
366
370
  relation
367
371
  end
368
372
 
369
- def construct_join_dependency(associations)
370
- ActiveRecord::Associations::JoinDependency.new(
371
- klass, table, associations
372
- )
373
- end
374
-
375
373
  def apply_join_dependency(eager_loading: group_values.empty?)
376
- join_dependency = construct_join_dependency(eager_load_values + includes_values)
374
+ join_dependency = construct_join_dependency(
375
+ eager_load_values + includes_values, Arel::Nodes::OuterJoin
376
+ )
377
377
  relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
378
378
 
379
379
  if eager_loading && !using_limitable_reflections?(join_dependency.reflections)
@@ -117,16 +117,16 @@ module ActiveRecord
117
117
  if other.klass == relation.klass
118
118
  relation.joins!(*other.joins_values)
119
119
  else
120
- joins_dependency = other.joins_values.map do |join|
120
+ associations, others = other.joins_values.partition do |join|
121
121
  case join
122
- when Hash, Symbol, Array
123
- other.send(:construct_join_dependency, join)
124
- else
125
- join
122
+ when Hash, Symbol, Array; true
126
123
  end
127
124
  end
128
125
 
129
- relation.joins!(*joins_dependency)
126
+ join_dependency = other.construct_join_dependency(
127
+ associations, Arel::Nodes::InnerJoin
128
+ )
129
+ relation.joins!(join_dependency, *others)
130
130
  end
131
131
  end
132
132
 
@@ -136,16 +136,11 @@ module ActiveRecord
136
136
  if other.klass == relation.klass
137
137
  relation.left_outer_joins!(*other.left_outer_joins_values)
138
138
  else
139
- joins_dependency = other.left_outer_joins_values.map do |join|
140
- case join
141
- when Hash, Symbol, Array
142
- other.send(:construct_join_dependency, join)
143
- else
144
- join
145
- end
146
- end
147
-
148
- relation.left_outer_joins!(*joins_dependency)
139
+ associations = other.left_outer_joins_values
140
+ join_dependency = other.construct_join_dependency(
141
+ associations, Arel::Nodes::OuterJoin
142
+ )
143
+ relation.joins!(join_dependency)
149
144
  end
150
145
  end
151
146
 
@@ -18,8 +18,10 @@ module ActiveRecord
18
18
  end
19
19
 
20
20
  def nil?
21
- !value_before_type_cast.is_a?(StatementCache::Substitute) &&
22
- (value_before_type_cast.nil? || value_for_database.nil?)
21
+ unless value_before_type_cast.is_a?(StatementCache::Substitute)
22
+ value_before_type_cast.nil? ||
23
+ type.respond_to?(:subtype, true) && value_for_database.nil?
24
+ end
23
25
  rescue ::RangeError
24
26
  end
25
27
 
@@ -32,7 +34,7 @@ module ActiveRecord
32
34
  if defined?(@_unboundable)
33
35
  @_unboundable
34
36
  else
35
- value_for_database
37
+ value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
36
38
  @_unboundable = nil
37
39
  end
38
40
  rescue ::RangeError