activerecord 5.1.3 → 5.1.4.rc1
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 +34 -0
- data/lib/active_record/associations.rb +32 -16
- data/lib/active_record/associations/association_scope.rb +12 -4
- data/lib/active_record/associations/collection_association.rb +6 -3
- data/lib/active_record/associations/has_one_association.rb +2 -0
- data/lib/active_record/associations/preloader/association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute.rb +1 -1
- data/lib/active_record/attribute_methods/dirty.rb +9 -9
- data/lib/active_record/collection_cache_key.rb +1 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +8 -9
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +0 -10
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/reflection.rb +6 -10
- data/lib/active_record/relation.rb +8 -0
- data/lib/active_record/relation/calculations.rb +23 -12
- data/lib/active_record/relation/where_clause.rb +2 -1
- data/lib/active_record/scoping/named.rb +11 -2
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/type/internal/abstract_json.rb +4 -0
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a6eda8b079f4604ae848be44d3c3f272b20cc90
|
4
|
+
data.tar.gz: 0244a2cff9dce5220301b717f6aac1690c101de7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba0aa505e0f08c935c134a4904f65b79861a51b16afd31fb08f713099e61b9e9a7418d79831bbd4eaf9e507b6db0af723396b380300f5fa7e4213d6d5a38ddf7
|
7
|
+
data.tar.gz: 3aa924d1ea393fb9f5501c4239617a7fc1f9a1e959d2f9eb6ba194fd89420dc226903b9a2df4297bd2c0c1585c3e7ced24fc83881b0ba88efb9401e277b2c5dc
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,37 @@
|
|
1
|
+
## Rails 5.1.4.rc1 (August 24, 2017) ##
|
2
|
+
|
3
|
+
* Ensure `sum` honors `distinct` on `has_many :through` associations
|
4
|
+
|
5
|
+
Fixes #16791
|
6
|
+
|
7
|
+
*Aaron Wortham
|
8
|
+
|
9
|
+
* Fix `COUNT(DISTINCT ...)` with `ORDER BY` and `LIMIT` to keep the existing select list.
|
10
|
+
|
11
|
+
*Ryuta Kamizono*
|
12
|
+
|
13
|
+
* Fix `unscoped(where: [columns])` removing the wrong bind values
|
14
|
+
|
15
|
+
When the `where` is called on a relation after a `or`, unscoping the column of that later `where`, it removed
|
16
|
+
bind values used by the `or` instead.
|
17
|
+
|
18
|
+
```
|
19
|
+
Post.where(id: 1).or(Post.where(id: 2)).where(foo: 3).unscope(where: :foo).to_sql
|
20
|
+
# Currently:
|
21
|
+
# SELECT "posts".* FROM "posts" WHERE ("posts"."id" = 2 OR "posts"."id" = 3)
|
22
|
+
# With fix:
|
23
|
+
# SELECT "posts".* FROM "posts" WHERE ("posts"."id" = 1 OR "posts"."id" = 2)
|
24
|
+
```
|
25
|
+
|
26
|
+
*Maxime Handfield Lapointe*
|
27
|
+
|
28
|
+
* When a `has_one` association is destroyed by `dependent: destroy`,
|
29
|
+
`destroyed_by_association` will now be set to the reflection, matching the
|
30
|
+
behaviour of `has_many` associations.
|
31
|
+
|
32
|
+
*Lisa Ugray*
|
33
|
+
|
34
|
+
|
1
35
|
## Rails 5.1.3 (August 03, 2017) ##
|
2
36
|
|
3
37
|
* No changes.
|
@@ -222,13 +222,6 @@ module ActiveRecord
|
|
222
222
|
autoload :CollectionAssociation
|
223
223
|
autoload :ForeignAssociation
|
224
224
|
autoload :CollectionProxy
|
225
|
-
|
226
|
-
autoload :BelongsToAssociation
|
227
|
-
autoload :BelongsToPolymorphicAssociation
|
228
|
-
autoload :HasManyAssociation
|
229
|
-
autoload :HasManyThroughAssociation
|
230
|
-
autoload :HasOneAssociation
|
231
|
-
autoload :HasOneThroughAssociation
|
232
225
|
autoload :ThroughAssociation
|
233
226
|
|
234
227
|
module Builder #:nodoc:
|
@@ -243,6 +236,13 @@ module ActiveRecord
|
|
243
236
|
end
|
244
237
|
|
245
238
|
eager_autoload do
|
239
|
+
autoload :BelongsToAssociation
|
240
|
+
autoload :BelongsToPolymorphicAssociation
|
241
|
+
autoload :HasManyAssociation
|
242
|
+
autoload :HasManyThroughAssociation
|
243
|
+
autoload :HasOneAssociation
|
244
|
+
autoload :HasOneThroughAssociation
|
245
|
+
|
246
246
|
autoload :Preloader
|
247
247
|
autoload :JoinDependency
|
248
248
|
autoload :AssociationScope
|
@@ -342,17 +342,18 @@ module ActiveRecord
|
|
342
342
|
# | | belongs_to |
|
343
343
|
# generated methods | belongs_to | :polymorphic | has_one
|
344
344
|
# ----------------------------------+------------+--------------+---------
|
345
|
-
# other
|
345
|
+
# other | X | X | X
|
346
346
|
# other=(other) | X | X | X
|
347
347
|
# build_other(attributes={}) | X | | X
|
348
348
|
# create_other(attributes={}) | X | | X
|
349
349
|
# create_other!(attributes={}) | X | | X
|
350
|
+
# reload_other | X | X | X
|
350
351
|
#
|
351
352
|
# === Collection associations (one-to-many / many-to-many)
|
352
353
|
# | | | has_many
|
353
354
|
# generated methods | habtm | has_many | :through
|
354
355
|
# ----------------------------------+-------+----------+----------
|
355
|
-
# others
|
356
|
+
# others | X | X | X
|
356
357
|
# others=(other,other,...) | X | X | X
|
357
358
|
# other_ids | X | X | X
|
358
359
|
# other_ids=(id,id,...) | X | X | X
|
@@ -376,6 +377,7 @@ module ActiveRecord
|
|
376
377
|
# others.exists? | X | X | X
|
377
378
|
# others.distinct | X | X | X
|
378
379
|
# others.reset | X | X | X
|
380
|
+
# others.reload | X | X | X
|
379
381
|
#
|
380
382
|
# === Overriding generated methods
|
381
383
|
#
|
@@ -1188,8 +1190,8 @@ module ActiveRecord
|
|
1188
1190
|
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
|
1189
1191
|
#
|
1190
1192
|
# [collection(force_reload = false)]
|
1191
|
-
# Returns
|
1192
|
-
# An empty
|
1193
|
+
# Returns a Relation of all the associated objects.
|
1194
|
+
# An empty Relation is returned if none are found.
|
1193
1195
|
# [collection<<(object, ...)]
|
1194
1196
|
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
1195
1197
|
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
|
@@ -1246,6 +1248,9 @@ module ActiveRecord
|
|
1246
1248
|
# [collection.create!(attributes = {})]
|
1247
1249
|
# Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
|
1248
1250
|
# if the record is invalid.
|
1251
|
+
# [collection.reload]
|
1252
|
+
# Returns a Relation of all of the associated objects, forcing a database read.
|
1253
|
+
# An empty Relation is returned if none are found.
|
1249
1254
|
#
|
1250
1255
|
# === Example
|
1251
1256
|
#
|
@@ -1265,6 +1270,7 @@ module ActiveRecord
|
|
1265
1270
|
# * <tt>Firm#clients.build</tt> (similar to <tt>Client.new("firm_id" => id)</tt>)
|
1266
1271
|
# * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save; c</tt>)
|
1267
1272
|
# * <tt>Firm#clients.create!</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save!</tt>)
|
1273
|
+
# * <tt>Firm#clients.reload</tt>
|
1268
1274
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1269
1275
|
#
|
1270
1276
|
# === Scopes
|
@@ -1407,7 +1413,7 @@ module ActiveRecord
|
|
1407
1413
|
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
|
1408
1414
|
# <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
|
1409
1415
|
#
|
1410
|
-
# [association
|
1416
|
+
# [association]
|
1411
1417
|
# Returns the associated object. +nil+ is returned if none is found.
|
1412
1418
|
# [association=(associate)]
|
1413
1419
|
# Assigns the associate object, extracts the primary key, sets it as the foreign key,
|
@@ -1424,6 +1430,8 @@ module ActiveRecord
|
|
1424
1430
|
# [create_association!(attributes = {})]
|
1425
1431
|
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1426
1432
|
# if the record is invalid.
|
1433
|
+
# [reload_association]
|
1434
|
+
# Returns the associated object, forcing a database read.
|
1427
1435
|
#
|
1428
1436
|
# === Example
|
1429
1437
|
#
|
@@ -1433,6 +1441,7 @@ module ActiveRecord
|
|
1433
1441
|
# * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new("account_id" => id)</tt>)
|
1434
1442
|
# * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save; b</tt>)
|
1435
1443
|
# * <tt>Account#create_beneficiary!</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save!; b</tt>)
|
1444
|
+
# * <tt>Account#reload_beneficiary</tt>
|
1436
1445
|
#
|
1437
1446
|
# === Scopes
|
1438
1447
|
#
|
@@ -1539,7 +1548,7 @@ module ActiveRecord
|
|
1539
1548
|
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
|
1540
1549
|
# <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
|
1541
1550
|
#
|
1542
|
-
# [association
|
1551
|
+
# [association]
|
1543
1552
|
# Returns the associated object. +nil+ is returned if none is found.
|
1544
1553
|
# [association=(associate)]
|
1545
1554
|
# Assigns the associate object, extracts the primary key, and sets it as the foreign key.
|
@@ -1553,6 +1562,8 @@ module ActiveRecord
|
|
1553
1562
|
# [create_association!(attributes = {})]
|
1554
1563
|
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1555
1564
|
# if the record is invalid.
|
1565
|
+
# [reload_association]
|
1566
|
+
# Returns the associated object, forcing a database read.
|
1556
1567
|
#
|
1557
1568
|
# === Example
|
1558
1569
|
#
|
@@ -1562,6 +1573,7 @@ module ActiveRecord
|
|
1562
1573
|
# * <tt>Post#build_author</tt> (similar to <tt>post.author = Author.new</tt>)
|
1563
1574
|
# * <tt>Post#create_author</tt> (similar to <tt>post.author = Author.new; post.author.save; post.author</tt>)
|
1564
1575
|
# * <tt>Post#create_author!</tt> (similar to <tt>post.author = Author.new; post.author.save!; post.author</tt>)
|
1576
|
+
# * <tt>Post#reload_author</tt>
|
1565
1577
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1566
1578
|
#
|
1567
1579
|
# === Scopes
|
@@ -1701,9 +1713,9 @@ module ActiveRecord
|
|
1701
1713
|
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
|
1702
1714
|
# <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
|
1703
1715
|
#
|
1704
|
-
# [collection
|
1705
|
-
# Returns
|
1706
|
-
# An empty
|
1716
|
+
# [collection]
|
1717
|
+
# Returns a Relation of all the associated objects.
|
1718
|
+
# An empty Relation is returned if none are found.
|
1707
1719
|
# [collection<<(object, ...)]
|
1708
1720
|
# Adds one or more objects to the collection by creating associations in the join table
|
1709
1721
|
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
|
@@ -1741,6 +1753,9 @@ module ActiveRecord
|
|
1741
1753
|
# Returns a new object of the collection type that has been instantiated
|
1742
1754
|
# with +attributes+, linked to this object through the join table, and that has already been
|
1743
1755
|
# saved (if it passed the validation).
|
1756
|
+
# [collection.reload]
|
1757
|
+
# Returns a Relation of all of the associated objects, forcing a database read.
|
1758
|
+
# An empty Relation is returned if none are found.
|
1744
1759
|
#
|
1745
1760
|
# === Example
|
1746
1761
|
#
|
@@ -1759,6 +1774,7 @@ module ActiveRecord
|
|
1759
1774
|
# * <tt>Developer#projects.exists?(...)</tt>
|
1760
1775
|
# * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("developer_id" => id)</tt>)
|
1761
1776
|
# * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("developer_id" => id); c.save; c</tt>)
|
1777
|
+
# * <tt>Developer#projects.reload</tt>
|
1762
1778
|
# The declaration may include an +options+ hash to specialize the behavior of the association.
|
1763
1779
|
#
|
1764
1780
|
# === Scopes
|
@@ -66,11 +66,11 @@ module ActiveRecord
|
|
66
66
|
foreign_key = join_keys.foreign_key
|
67
67
|
|
68
68
|
value = transform_value(owner[foreign_key])
|
69
|
-
scope = scope
|
69
|
+
scope = apply_scope(scope, table, key, value)
|
70
70
|
|
71
71
|
if reflection.type
|
72
72
|
polymorphic_type = transform_value(owner.class.base_class.name)
|
73
|
-
scope = scope
|
73
|
+
scope = apply_scope(scope, table, reflection.type, polymorphic_type)
|
74
74
|
end
|
75
75
|
|
76
76
|
scope
|
@@ -89,10 +89,10 @@ module ActiveRecord
|
|
89
89
|
|
90
90
|
if reflection.type
|
91
91
|
value = transform_value(next_reflection.klass.base_class.name)
|
92
|
-
scope = scope
|
92
|
+
scope = apply_scope(scope, table, reflection.type, value)
|
93
93
|
end
|
94
94
|
|
95
|
-
scope
|
95
|
+
scope.joins!(join(foreign_table, constraint))
|
96
96
|
end
|
97
97
|
|
98
98
|
class ReflectionProxy < SimpleDelegator # :nodoc:
|
@@ -163,6 +163,14 @@ module ActiveRecord
|
|
163
163
|
scope
|
164
164
|
end
|
165
165
|
|
166
|
+
def apply_scope(scope, table, key, value)
|
167
|
+
if scope.table == table
|
168
|
+
scope.where!(key => value)
|
169
|
+
else
|
170
|
+
scope.where!(table.name => { key => value })
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
166
174
|
def eval_scope(klass, table, scope, owner)
|
167
175
|
predicate_builder = PredicateBuilder.new(TableMetadata.new(klass, table))
|
168
176
|
ActiveRecord::Relation.create(klass, table, predicate_builder).instance_exec(owner, &scope)
|
@@ -53,11 +53,14 @@ module ActiveRecord
|
|
53
53
|
pk_type = reflection.association_primary_key_type
|
54
54
|
ids = Array(ids).reject(&:blank?)
|
55
55
|
ids.map! { |i| pk_type.cast(i) }
|
56
|
-
|
57
|
-
|
56
|
+
|
57
|
+
primary_key = reflection.association_primary_key
|
58
|
+
records = klass.where(primary_key => ids).index_by do |r|
|
59
|
+
r.public_send(primary_key)
|
58
60
|
end.values_at(*ids).compact
|
61
|
+
|
59
62
|
if records.size != ids.size
|
60
|
-
klass.all.raise_record_not_found_exception!(ids, records.size, ids.size,
|
63
|
+
klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key)
|
61
64
|
else
|
62
65
|
replace(records)
|
63
66
|
end
|
@@ -56,6 +56,7 @@ module ActiveRecord
|
|
56
56
|
when :delete
|
57
57
|
target.delete
|
58
58
|
when :destroy
|
59
|
+
target.destroyed_by_association = reflection
|
59
60
|
target.destroy
|
60
61
|
when :nullify
|
61
62
|
target.update_columns(reflection.foreign_key => nil) if target.persisted?
|
@@ -78,6 +79,7 @@ module ActiveRecord
|
|
78
79
|
when :delete
|
79
80
|
target.delete
|
80
81
|
when :destroy
|
82
|
+
target.destroyed_by_association = reflection
|
81
83
|
target.destroy
|
82
84
|
else
|
83
85
|
nullify_owner_attributes(target)
|
@@ -13,7 +13,7 @@ module ActiveRecord
|
|
13
13
|
def target_scope
|
14
14
|
scope = super
|
15
15
|
reflection.chain.drop(1).each do |reflection|
|
16
|
-
relation = reflection.klass.
|
16
|
+
relation = reflection.klass.scope_for_association
|
17
17
|
scope.merge!(
|
18
18
|
relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load)
|
19
19
|
)
|
@@ -122,7 +122,7 @@ module ActiveRecord
|
|
122
122
|
|
123
123
|
def encode_with(coder)
|
124
124
|
coder["name"] = name
|
125
|
-
coder["value_before_type_cast"] = value_before_type_cast
|
125
|
+
coder["value_before_type_cast"] = value_before_type_cast unless value_before_type_cast.nil?
|
126
126
|
coder["type"] = type if type
|
127
127
|
coder["original_attribute"] = original_attribute if original_attribute
|
128
128
|
coder["value"] = value if defined?(@value)
|
@@ -4,7 +4,7 @@ require "active_record/attribute_mutation_tracker"
|
|
4
4
|
|
5
5
|
module ActiveRecord
|
6
6
|
module AttributeMethods
|
7
|
-
module Dirty
|
7
|
+
module Dirty
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
10
|
include ActiveModel::Dirty
|
@@ -68,33 +68,33 @@ module ActiveRecord
|
|
68
68
|
@mutations_from_database = AttributeMutationTracker.new(@attributes)
|
69
69
|
end
|
70
70
|
|
71
|
-
def changes_applied
|
71
|
+
def changes_applied # :nodoc:
|
72
72
|
@previous_mutation_tracker = mutation_tracker
|
73
73
|
@changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
|
74
74
|
clear_mutation_trackers
|
75
75
|
end
|
76
76
|
|
77
|
-
def clear_changes_information
|
77
|
+
def clear_changes_information # :nodoc:
|
78
78
|
@previous_mutation_tracker = nil
|
79
79
|
@changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
|
80
80
|
forget_attribute_assignments
|
81
81
|
clear_mutation_trackers
|
82
82
|
end
|
83
83
|
|
84
|
-
def raw_write_attribute(attr_name, *)
|
84
|
+
def raw_write_attribute(attr_name, *) # :nodoc:
|
85
85
|
result = super
|
86
86
|
clear_attribute_change(attr_name)
|
87
87
|
result
|
88
88
|
end
|
89
89
|
|
90
|
-
def clear_attribute_changes(attr_names)
|
90
|
+
def clear_attribute_changes(attr_names) # :nodoc:
|
91
91
|
super
|
92
92
|
attr_names.each do |attr_name|
|
93
93
|
clear_attribute_change(attr_name)
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
def changed_attributes
|
97
|
+
def changed_attributes # :nodoc:
|
98
98
|
# This should only be set by methods which will call changed_attributes
|
99
99
|
# multiple times when it is known that the computed value cannot change.
|
100
100
|
if defined?(@cached_changed_attributes)
|
@@ -105,14 +105,14 @@ module ActiveRecord
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
def changes
|
108
|
+
def changes # :nodoc:
|
109
109
|
cache_changed_attributes do
|
110
110
|
emit_warning_if_needed("changes", "saved_changes")
|
111
111
|
super
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
def previous_changes
|
115
|
+
def previous_changes # :nodoc:
|
116
116
|
unless previous_mutation_tracker.equal?(mutations_before_last_save)
|
117
117
|
ActiveSupport::Deprecation.warn(<<-EOW.strip_heredoc)
|
118
118
|
The behavior of `previous_changes` inside of after callbacks is
|
@@ -124,7 +124,7 @@ module ActiveRecord
|
|
124
124
|
previous_mutation_tracker.changes
|
125
125
|
end
|
126
126
|
|
127
|
-
def attribute_changed_in_place?(attr_name)
|
127
|
+
def attribute_changed_in_place?(attr_name) # :nodoc:
|
128
128
|
mutation_tracker.changed_in_place?(attr_name)
|
129
129
|
end
|
130
130
|
|
@@ -14,7 +14,7 @@ module ActiveRecord
|
|
14
14
|
column = "#{connection.quote_table_name(collection.table_name)}.#{connection.quote_column_name(timestamp_column)}"
|
15
15
|
select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
|
16
16
|
|
17
|
-
if collection.
|
17
|
+
if collection.has_limit_or_offset?
|
18
18
|
query = collection.spawn
|
19
19
|
query.select_values = [column]
|
20
20
|
subquery_alias = "subquery_for_cache_key"
|
@@ -71,12 +71,12 @@ module ActiveRecord
|
|
71
71
|
@statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
|
72
72
|
|
73
73
|
if version < "5.1.10"
|
74
|
-
raise "Your version of MySQL (#{
|
74
|
+
raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.1.10."
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
78
|
def version #:nodoc:
|
79
|
-
@version ||= Version.new(
|
79
|
+
@version ||= Version.new(version_string)
|
80
80
|
end
|
81
81
|
|
82
82
|
def mariadb? # :nodoc:
|
@@ -340,8 +340,8 @@ module ActiveRecord
|
|
340
340
|
|
341
341
|
def new_column_from_field(table_name, field) # :nodoc:
|
342
342
|
type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
|
343
|
-
if type_metadata.type == :datetime && field[:Default]
|
344
|
-
default, default_function = nil,
|
343
|
+
if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\(\))?\z/i.match?(field[:Default])
|
344
|
+
default, default_function = nil, "CURRENT_TIMESTAMP"
|
345
345
|
else
|
346
346
|
default, default_function = field[:Default], nil
|
347
347
|
end
|
@@ -914,12 +914,11 @@ module ActiveRecord
|
|
914
914
|
end
|
915
915
|
end
|
916
916
|
|
917
|
+
def version_string
|
918
|
+
full_version.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
|
919
|
+
end
|
920
|
+
|
917
921
|
class MysqlJson < Type::Internal::AbstractJson # :nodoc:
|
918
|
-
def changed_in_place?(raw_old_value, new_value)
|
919
|
-
# Normalization is required because MySQL JSON data format includes
|
920
|
-
# the space between the elements.
|
921
|
-
super(serialize(deserialize(raw_old_value)), new_value)
|
922
|
-
end
|
923
922
|
end
|
924
923
|
|
925
924
|
class MysqlString < Type::String # :nodoc:
|
@@ -53,7 +53,7 @@ module ActiveRecord
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def extract_expression_for_virtual_column(column)
|
56
|
-
if mariadb?
|
56
|
+
if mariadb? && version < "10.2.5"
|
57
57
|
create_table_info = create_table_info(column.table_name)
|
58
58
|
if %r/#{quote_column_name(column.name)} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info
|
59
59
|
$~[:expression].inspect
|
@@ -6,16 +6,6 @@ module ActiveRecord
|
|
6
6
|
def type
|
7
7
|
:jsonb
|
8
8
|
end
|
9
|
-
|
10
|
-
def changed_in_place?(raw_old_value, new_value)
|
11
|
-
# Postgres does not preserve insignificant whitespaces when
|
12
|
-
# round-tripping jsonb columns. This causes some false positives for
|
13
|
-
# the comparison here. Therefore, we need to parse and re-dump the
|
14
|
-
# raw value here to ensure the insignificant whitespaces are
|
15
|
-
# consistent with our encoder's output.
|
16
|
-
raw_old_value = serialize(deserialize(raw_old_value))
|
17
|
-
super(raw_old_value, new_value)
|
18
|
-
end
|
19
9
|
end
|
20
10
|
end
|
21
11
|
end
|
@@ -197,16 +197,8 @@ module ActiveRecord
|
|
197
197
|
end
|
198
198
|
|
199
199
|
def klass_join_scope(table, predicate_builder) # :nodoc:
|
200
|
-
|
201
|
-
|
202
|
-
else
|
203
|
-
relation = ActiveRecord::Relation.create(
|
204
|
-
klass,
|
205
|
-
table,
|
206
|
-
predicate_builder,
|
207
|
-
)
|
208
|
-
klass.send(:build_default_scope, relation)
|
209
|
-
end
|
200
|
+
relation = ActiveRecord::Relation.create(klass, table, predicate_builder)
|
201
|
+
klass.scope_for_association(relation)
|
210
202
|
end
|
211
203
|
|
212
204
|
def constraints
|
@@ -692,6 +684,10 @@ module ActiveRecord
|
|
692
684
|
Associations::HasManyAssociation
|
693
685
|
end
|
694
686
|
end
|
687
|
+
|
688
|
+
def association_primary_key(klass = nil)
|
689
|
+
primary_key(klass || self.klass)
|
690
|
+
end
|
695
691
|
end
|
696
692
|
|
697
693
|
class HasOneReflection < AssociationReflection # :nodoc:
|
@@ -642,6 +642,14 @@ module ActiveRecord
|
|
642
642
|
"#<#{self.class.name} [#{entries.join(', ')}]>"
|
643
643
|
end
|
644
644
|
|
645
|
+
def empty_scope? # :nodoc:
|
646
|
+
@values == klass.unscoped.values
|
647
|
+
end
|
648
|
+
|
649
|
+
def has_limit_or_offset? # :nodoc:
|
650
|
+
limit_value || offset_value
|
651
|
+
end
|
652
|
+
|
645
653
|
protected
|
646
654
|
|
647
655
|
def load_records(records)
|
@@ -111,7 +111,7 @@ module ActiveRecord
|
|
111
111
|
def calculate(operation, column_name)
|
112
112
|
if has_include?(column_name)
|
113
113
|
relation = construct_relation_for_association_calculations
|
114
|
-
relation
|
114
|
+
relation.distinct! if operation.to_s.downcase == "count"
|
115
115
|
|
116
116
|
relation.calculate(operation, column_name)
|
117
117
|
else
|
@@ -194,8 +194,13 @@ module ActiveRecord
|
|
194
194
|
|
195
195
|
if operation == "count"
|
196
196
|
column_name ||= select_for_count
|
197
|
-
|
198
|
-
|
197
|
+
if column_name == :all
|
198
|
+
if distinct && !(has_limit_or_offset? && order_values.any?)
|
199
|
+
column_name = primary_key
|
200
|
+
end
|
201
|
+
elsif column_name =~ /\s*DISTINCT[\s(]+/i
|
202
|
+
distinct = nil
|
203
|
+
end
|
199
204
|
end
|
200
205
|
|
201
206
|
if group_values.any?
|
@@ -222,7 +227,7 @@ module ActiveRecord
|
|
222
227
|
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
|
223
228
|
column_alias = column_name
|
224
229
|
|
225
|
-
if operation == "count" &&
|
230
|
+
if operation == "count" && has_limit_or_offset?
|
226
231
|
# Shortcut when limit is zero.
|
227
232
|
return 0 if limit_value == 0
|
228
233
|
|
@@ -234,6 +239,9 @@ module ActiveRecord
|
|
234
239
|
column = aggregate_column(column_name)
|
235
240
|
|
236
241
|
select_value = operation_over_aggregate_column(column, operation, distinct)
|
242
|
+
if operation == "sum" && distinct
|
243
|
+
select_value.distinct = true
|
244
|
+
end
|
237
245
|
|
238
246
|
column_alias = select_value.alias
|
239
247
|
column_alias ||= @klass.connection.column_name_for_operation(operation, select_value)
|
@@ -361,16 +369,19 @@ module ActiveRecord
|
|
361
369
|
end
|
362
370
|
|
363
371
|
def build_count_subquery(relation, column_name, distinct)
|
364
|
-
|
365
|
-
|
372
|
+
relation.select_values = [
|
373
|
+
if column_name == :all
|
374
|
+
distinct ? table[Arel.star] : Arel.sql("1")
|
375
|
+
else
|
376
|
+
column_alias = Arel.sql("count_column")
|
377
|
+
aggregate_column(column_name).as(column_alias)
|
378
|
+
end
|
379
|
+
]
|
366
380
|
|
367
|
-
|
368
|
-
|
369
|
-
subquery = relation.arel.as(subquery_alias)
|
381
|
+
subquery = relation.arel.as(Arel.sql("subquery_for_count"))
|
382
|
+
select_value = operation_over_aggregate_column(column_alias || Arel.star, "count", false)
|
370
383
|
|
371
|
-
|
372
|
-
select_value = operation_over_aggregate_column(column_alias, "count", distinct)
|
373
|
-
sm.project(select_value).from(subquery)
|
384
|
+
Arel::SelectManager.new(subquery).project(select_value)
|
374
385
|
end
|
375
386
|
end
|
376
387
|
end
|
@@ -136,10 +136,11 @@ module ActiveRecord
|
|
136
136
|
binds_index = 0
|
137
137
|
|
138
138
|
predicates = self.predicates.reject do |node|
|
139
|
+
binds_contains = node.grep(Arel::Nodes::BindParam).size if node.is_a?(Arel::Nodes::Node)
|
140
|
+
|
139
141
|
except = \
|
140
142
|
case node
|
141
143
|
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
|
142
|
-
binds_contains = node.grep(Arel::Nodes::BindParam).size
|
143
144
|
subrelation = (node.left.kind_of?(Arel::Attributes::Attribute) ? node.left : node.right)
|
144
145
|
columns.include?(subrelation.name.to_s)
|
145
146
|
end
|
@@ -29,8 +29,17 @@ module ActiveRecord
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
|
32
|
+
def scope_for_association(scope = relation) # :nodoc:
|
33
|
+
current_scope = self.current_scope
|
34
|
+
|
35
|
+
if current_scope && current_scope.empty_scope?
|
36
|
+
scope
|
37
|
+
else
|
38
|
+
default_scoped(scope)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def default_scoped(scope = relation) # :nodoc:
|
34
43
|
build_default_scope(scope) || scope
|
35
44
|
end
|
36
45
|
|
@@ -20,7 +20,7 @@ module ActiveRecord
|
|
20
20
|
configuration.merge("encoding" => encoding)
|
21
21
|
establish_connection configuration
|
22
22
|
rescue ActiveRecord::StatementInvalid => error
|
23
|
-
if
|
23
|
+
if error.cause.is_a?(PG::DuplicateDatabase)
|
24
24
|
raise DatabaseAlreadyExists
|
25
25
|
else
|
26
26
|
raise
|
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: 5.1.
|
4
|
+
version: 5.1.4.rc1
|
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: 2017-08-
|
11
|
+
date: 2017-08-24 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: 5.1.
|
19
|
+
version: 5.1.4.rc1
|
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: 5.1.
|
26
|
+
version: 5.1.4.rc1
|
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: 5.1.
|
33
|
+
version: 5.1.4.rc1
|
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: 5.1.
|
40
|
+
version: 5.1.4.rc1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: arel
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -333,9 +333,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
333
333
|
version: 2.2.2
|
334
334
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
335
335
|
requirements:
|
336
|
-
- - "
|
336
|
+
- - ">"
|
337
337
|
- !ruby/object:Gem::Version
|
338
|
-
version:
|
338
|
+
version: 1.3.1
|
339
339
|
requirements: []
|
340
340
|
rubyforge_project:
|
341
341
|
rubygems_version: 2.6.12
|