activerecord 6.0.0.beta1 → 6.0.0.beta2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +99 -2
- data/lib/active_record.rb +7 -0
- data/lib/active_record/associations/association.rb +17 -0
- data/lib/active_record/associations/collection_association.rb +5 -6
- data/lib/active_record/associations/collection_proxy.rb +12 -41
- data/lib/active_record/associations/has_many_association.rb +1 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +11 -6
- data/lib/active_record/associations/preloader/association.rb +3 -4
- data/lib/active_record/associations/preloader/through_association.rb +9 -20
- data/lib/active_record/callbacks.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +25 -12
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +17 -9
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +5 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +47 -33
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +16 -8
- data/lib/active_record/connection_adapters/abstract/transaction.rb +5 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +6 -4
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +28 -65
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +59 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +98 -89
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +30 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +27 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +8 -5
- data/lib/active_record/connection_handling.rb +9 -4
- data/lib/active_record/core.rb +13 -1
- data/lib/active_record/database_configurations.rb +30 -10
- data/lib/active_record/database_configurations/hash_config.rb +1 -1
- data/lib/active_record/database_configurations/url_config.rb +9 -4
- data/lib/active_record/errors.rb +17 -12
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +90 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/migration/compatibility.rb +62 -63
- data/lib/active_record/persistence.rb +6 -6
- data/lib/active_record/querying.rb +2 -3
- data/lib/active_record/railtie.rb +9 -0
- data/lib/active_record/railties/collection_cache_association_loading.rb +3 -3
- data/lib/active_record/reflection.rb +15 -29
- data/lib/active_record/relation.rb +86 -15
- data/lib/active_record/relation/calculations.rb +2 -4
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +8 -4
- data/lib/active_record/relation/query_attribute.rb +5 -3
- data/lib/active_record/relation/query_methods.rb +28 -8
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +1 -5
- data/lib/active_record/scoping.rb +6 -7
- data/lib/active_record/scoping/default.rb +1 -8
- data/lib/active_record/scoping/named.rb +9 -1
- data/lib/active_record/test_fixtures.rb +2 -2
- data/lib/active_record/timestamp.rb +9 -3
- data/lib/active_record/validations/uniqueness.rb +3 -1
- data/lib/arel.rb +7 -0
- data/lib/arel/nodes/and.rb +1 -1
- data/lib/arel/nodes/case.rb +1 -1
- metadata +11 -8
@@ -186,11 +186,9 @@ module ActiveRecord
|
|
186
186
|
relation = apply_join_dependency
|
187
187
|
relation.pluck(*column_names)
|
188
188
|
else
|
189
|
-
disallow_raw_sql!(column_names)
|
189
|
+
klass.disallow_raw_sql!(column_names)
|
190
190
|
relation = spawn
|
191
|
-
relation.select_values = column_names
|
192
|
-
@klass.has_attribute?(cn) || @klass.attribute_alias?(cn) ? arel_attribute(cn) : cn
|
193
|
-
}
|
191
|
+
relation.select_values = column_names
|
194
192
|
result = skip_query_cache_if_necessary { klass.connection.select_all(relation.arel, nil) }
|
195
193
|
result.cast_values(klass.attribute_types)
|
196
194
|
end
|
@@ -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.
|
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
|
-
|
355
|
+
conditions = sanitize_forbidden_attributes(conditions)
|
356
|
+
|
357
|
+
if distinct_value && offset_value
|
358
|
+
relation = 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
|
@@ -18,8 +18,10 @@ module ActiveRecord
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def nil?
|
21
|
-
|
22
|
-
|
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
|
@@ -1052,11 +1052,13 @@ module ActiveRecord
|
|
1052
1052
|
|
1053
1053
|
def arel_columns(columns)
|
1054
1054
|
columns.flat_map do |field|
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
connection.quote_table_name(field
|
1059
|
-
|
1055
|
+
case field
|
1056
|
+
when Symbol
|
1057
|
+
field = field.to_s
|
1058
|
+
arel_column(field) { connection.quote_table_name(field) }
|
1059
|
+
when String
|
1060
|
+
arel_column(field) { field }
|
1061
|
+
when Proc
|
1060
1062
|
field.call
|
1061
1063
|
else
|
1062
1064
|
field
|
@@ -1064,6 +1066,18 @@ module ActiveRecord
|
|
1064
1066
|
end
|
1065
1067
|
end
|
1066
1068
|
|
1069
|
+
def arel_column(field)
|
1070
|
+
field = klass.attribute_alias(field) if klass.attribute_alias?(field)
|
1071
|
+
from = from_clause.name || from_clause.value
|
1072
|
+
|
1073
|
+
if klass.columns_hash.key?(field) &&
|
1074
|
+
(!from || from == table.name || from == connection.quote_table_name(table.name))
|
1075
|
+
arel_attribute(field)
|
1076
|
+
else
|
1077
|
+
yield
|
1078
|
+
end
|
1079
|
+
end
|
1080
|
+
|
1067
1081
|
def reverse_sql_order(order_query)
|
1068
1082
|
if order_query.empty?
|
1069
1083
|
return [arel_attribute(primary_key).desc] if primary_key
|
@@ -1099,7 +1113,7 @@ module ActiveRecord
|
|
1099
1113
|
# Uses SQL function with multiple arguments.
|
1100
1114
|
(order.include?(",") && order.split(",").find { |section| section.count("(") != section.count(")") }) ||
|
1101
1115
|
# Uses "nulls first" like construction.
|
1102
|
-
|
1116
|
+
/\bnulls\s+(?:first|last)\b/i.match?(order)
|
1103
1117
|
end
|
1104
1118
|
|
1105
1119
|
def build_order(arel)
|
@@ -1145,14 +1159,20 @@ module ActiveRecord
|
|
1145
1159
|
order_args.map! do |arg|
|
1146
1160
|
case arg
|
1147
1161
|
when Symbol
|
1148
|
-
|
1162
|
+
arg = arg.to_s
|
1163
|
+
arel_column(arg) {
|
1164
|
+
Arel.sql(connection.quote_table_name(arg))
|
1165
|
+
}.asc
|
1149
1166
|
when Hash
|
1150
1167
|
arg.map { |field, dir|
|
1151
1168
|
case field
|
1152
1169
|
when Arel::Nodes::SqlLiteral
|
1153
1170
|
field.send(dir.downcase)
|
1154
1171
|
else
|
1155
|
-
|
1172
|
+
field = field.to_s
|
1173
|
+
arel_column(field) {
|
1174
|
+
Arel.sql(connection.quote_table_name(field))
|
1175
|
+
}.send(dir.downcase)
|
1156
1176
|
end
|
1157
1177
|
}
|
1158
1178
|
else
|
@@ -8,7 +8,7 @@ module ActiveRecord
|
|
8
8
|
module SpawnMethods
|
9
9
|
# This is overridden by Associations::CollectionProxy
|
10
10
|
def spawn #:nodoc:
|
11
|
-
|
11
|
+
already_in_scope? ? klass.all : clone
|
12
12
|
end
|
13
13
|
|
14
14
|
# Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an ActiveRecord::Relation.
|
@@ -140,11 +140,7 @@ module ActiveRecord
|
|
140
140
|
|
141
141
|
def except_predicates(columns)
|
142
142
|
predicates.reject do |node|
|
143
|
-
|
144
|
-
when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual
|
145
|
-
subrelation = (node.left.kind_of?(Arel::Attributes::Attribute) ? node.left : node.right)
|
146
|
-
columns.include?(subrelation.name.to_s)
|
147
|
-
end
|
143
|
+
Arel.fetch_attribute(node) { |attr| columns.include?(attr.name.to_s) }
|
148
144
|
end
|
149
145
|
end
|
150
146
|
|
@@ -23,14 +23,13 @@ module ActiveRecord
|
|
23
23
|
current_scope
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
26
|
+
def current_scope(skip_inherited_scope = false)
|
27
|
+
ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
def current_scope=(scope)
|
31
|
+
ScopeRegistry.set_value_for(:current_scope, self, scope)
|
32
|
+
end
|
34
33
|
end
|
35
34
|
|
36
35
|
def populate_with_current_scope_attributes # :nodoc:
|
@@ -31,14 +31,7 @@ module ActiveRecord
|
|
31
31
|
# Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
|
32
32
|
# }
|
33
33
|
def unscoped
|
34
|
-
block_given? ?
|
35
|
-
end
|
36
|
-
|
37
|
-
def _scoping(relation) # :nodoc:
|
38
|
-
previous, self.current_scope = current_scope(true), relation
|
39
|
-
yield
|
40
|
-
ensure
|
41
|
-
self.current_scope = previous
|
34
|
+
block_given? ? relation.scoping { yield } : relation
|
42
35
|
end
|
43
36
|
|
44
37
|
# Are there attributes associated with this scope?
|
@@ -27,6 +27,14 @@ module ActiveRecord
|
|
27
27
|
scope = current_scope
|
28
28
|
|
29
29
|
if scope
|
30
|
+
if scope._deprecated_scope_source
|
31
|
+
ActiveSupport::Deprecation.warn(<<~MSG.squish)
|
32
|
+
Class level methods will no longer inherit scoping from `#{scope._deprecated_scope_source}`
|
33
|
+
in Rails 6.1. To continue using the scoped relation, pass it into the block directly.
|
34
|
+
To instead access the full set of models, as Rails 6.1 will, use `#{name}.unscoped`.
|
35
|
+
MSG
|
36
|
+
end
|
37
|
+
|
30
38
|
if self == scope.klass
|
31
39
|
scope.clone
|
32
40
|
else
|
@@ -180,7 +188,7 @@ module ActiveRecord
|
|
180
188
|
|
181
189
|
if body.respond_to?(:to_proc)
|
182
190
|
singleton_class.define_method(name) do |*args|
|
183
|
-
scope = all._exec_scope(*args, &body)
|
191
|
+
scope = all._exec_scope(name, *args, &body)
|
184
192
|
scope = scope.extending(extension) if extension
|
185
193
|
scope
|
186
194
|
end
|
@@ -122,7 +122,7 @@ module ActiveRecord
|
|
122
122
|
# Begin transactions for connections already established
|
123
123
|
@fixture_connections = enlist_fixture_connections
|
124
124
|
@fixture_connections.each do |connection|
|
125
|
-
connection.begin_transaction joinable: false
|
125
|
+
connection.begin_transaction joinable: false, _lazy: false
|
126
126
|
connection.pool.lock_thread = true if lock_threads
|
127
127
|
end
|
128
128
|
|
@@ -138,7 +138,7 @@ module ActiveRecord
|
|
138
138
|
end
|
139
139
|
|
140
140
|
if connection && !@fixture_connections.include?(connection)
|
141
|
-
connection.begin_transaction joinable: false
|
141
|
+
connection.begin_transaction joinable: false, _lazy: false
|
142
142
|
connection.pool.lock_thread = true if lock_threads
|
143
143
|
@fixture_connections << connection
|
144
144
|
end
|
@@ -101,8 +101,8 @@ module ActiveRecord
|
|
101
101
|
super
|
102
102
|
end
|
103
103
|
|
104
|
-
def _update_record
|
105
|
-
if
|
104
|
+
def _update_record
|
105
|
+
if @_touch_record && should_record_timestamps?
|
106
106
|
current_time = current_time_from_proper_timezone
|
107
107
|
|
108
108
|
timestamp_attributes_for_update_in_model.each do |column|
|
@@ -110,7 +110,13 @@ module ActiveRecord
|
|
110
110
|
_write_attribute(column, current_time)
|
111
111
|
end
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
|
+
super
|
115
|
+
end
|
116
|
+
|
117
|
+
def create_or_update(touch: true, **)
|
118
|
+
@_touch_record = touch
|
119
|
+
super
|
114
120
|
end
|
115
121
|
|
116
122
|
def should_record_timestamps?
|
@@ -12,7 +12,7 @@ module ActiveRecord
|
|
12
12
|
raise ArgumentError, "#{options[:scope]} is not supported format for :scope option. " \
|
13
13
|
"Pass a symbol or an array of symbols instead: `scope: :user_id`"
|
14
14
|
end
|
15
|
-
super
|
15
|
+
super
|
16
16
|
@klass = options[:class]
|
17
17
|
end
|
18
18
|
|
@@ -62,6 +62,8 @@ module ActiveRecord
|
|
62
62
|
|
63
63
|
if bind.nil?
|
64
64
|
attr.eq(bind)
|
65
|
+
elsif !options.key?(:case_sensitive)
|
66
|
+
klass.connection.default_uniqueness_comparison(attr, bind)
|
65
67
|
elsif options[:case_sensitive]
|
66
68
|
klass.connection.case_sensitive_comparison(attr, bind)
|
67
69
|
else
|
data/lib/arel.rb
CHANGED
@@ -39,6 +39,13 @@ module Arel # :nodoc: all
|
|
39
39
|
value.is_a?(Arel::Node) || value.is_a?(Arel::Attribute) || value.is_a?(Arel::Nodes::SqlLiteral)
|
40
40
|
end
|
41
41
|
|
42
|
+
def self.fetch_attribute(value)
|
43
|
+
case value
|
44
|
+
when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual
|
45
|
+
yield value.left.is_a?(Arel::Attributes::Attribute) ? value.left : value.right
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
42
49
|
## Convenience Alias
|
43
50
|
Node = Arel::Nodes::Node
|
44
51
|
end
|
data/lib/arel/nodes/and.rb
CHANGED
data/lib/arel/nodes/case.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0.
|
4
|
+
version: 6.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0.0.
|
19
|
+
version: 6.0.0.beta2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.0.0.
|
26
|
+
version: 6.0.0.beta2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 6.0.0.
|
33
|
+
version: 6.0.0.beta2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 6.0.0.
|
40
|
+
version: 6.0.0.beta2
|
41
41
|
description: Databases on Rails. Build a persistent domain model by mapping database
|
42
42
|
tables to Ruby classes. Strong conventions for associations, validations, aggregations,
|
43
43
|
migrations, and testing come baked-in.
|
@@ -202,6 +202,9 @@ files:
|
|
202
202
|
- lib/active_record/locking/optimistic.rb
|
203
203
|
- lib/active_record/locking/pessimistic.rb
|
204
204
|
- lib/active_record/log_subscriber.rb
|
205
|
+
- lib/active_record/middleware/database_selector.rb
|
206
|
+
- lib/active_record/middleware/database_selector/resolver.rb
|
207
|
+
- lib/active_record/middleware/database_selector/resolver/session.rb
|
205
208
|
- lib/active_record/migration.rb
|
206
209
|
- lib/active_record/migration/command_recorder.rb
|
207
210
|
- lib/active_record/migration/compatibility.rb
|
@@ -385,8 +388,8 @@ homepage: http://rubyonrails.org
|
|
385
388
|
licenses:
|
386
389
|
- MIT
|
387
390
|
metadata:
|
388
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.0.0.
|
389
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.0.0.
|
391
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.0.0.beta2/activerecord
|
392
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.0.0.beta2/activerecord/CHANGELOG.md
|
390
393
|
post_install_message:
|
391
394
|
rdoc_options:
|
392
395
|
- "--main"
|