activerecord 5.1.6.2 → 5.1.7.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 +17 -0
- data/lib/active_record/associations/belongs_to_association.rb +1 -1
- data/lib/active_record/associations/builder/belongs_to.rb +2 -1
- data/lib/active_record/attribute_methods/dirty.rb +2 -2
- data/lib/active_record/attribute_mutation_tracker.rb +9 -1
- data/lib/active_record/callbacks.rb +4 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +3 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -0
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +18 -8
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +11 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +9 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
- data/lib/active_record/counter_cache.rb +10 -12
- data/lib/active_record/errors.rb +18 -12
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/model_schema.rb +1 -1
- data/lib/active_record/persistence.rb +3 -2
- data/lib/active_record/relation/finder_methods.rb +2 -2
- data/lib/active_record/relation/predicate_builder.rb +2 -2
- data/lib/active_record/relation/query_methods.rb +1 -1
- data/lib/active_record/tasks/database_tasks.rb +1 -1
- data/lib/active_record/timestamp.rb +7 -0
- data/lib/active_record/type/serialized.rb +4 -0
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6148c87ad69abae38d0fb9dc68a93a4e74245b8cab51655cae154aa9071378d2
|
4
|
+
data.tar.gz: ecb3927ddf8bd39369cbb54d53500388d08dbbb38d0a75d34cae258cdbea32ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6aa5d88e07b70625aa7bd6aa12a136abc80da1444a492076f72e7f44b4edaee4bf9c85dd44ae61f5d196f39da58739fbb9d93355fc4de2177af882a1932d8eaf
|
7
|
+
data.tar.gz: 59c1baec317ea025f115c975db9aaf5f89f96604a92d1e11c31ed8b5b1876946ccbd5f4ed396c29f841fb3c694f24f5bbff5412a6a9a73a92f97ceb244853d52
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
## Rails 5.1.7.rc1 (March 22, 2019) ##
|
2
|
+
|
3
|
+
* Fix `touch` option to behave consistently with `Persistence#touch` method.
|
4
|
+
|
5
|
+
*Ryuta Kamizono*
|
6
|
+
|
7
|
+
* Back port Rails 5.2 `reverse_order` Arel SQL literal fix.
|
8
|
+
|
9
|
+
*Matt Jones*, *Brooke Kuhlmann*
|
10
|
+
|
11
|
+
* `becomes` should clear the mutation tracker which is created in `after_initialize`.
|
12
|
+
|
13
|
+
Fixes #32867.
|
14
|
+
|
15
|
+
*Ryuta Kamizono*
|
16
|
+
|
17
|
+
|
1
18
|
## Rails 5.1.6.2 (March 11, 2019) ##
|
2
19
|
|
3
20
|
* No changes.
|
@@ -65,7 +65,7 @@ module ActiveRecord
|
|
65
65
|
def update_counters_on_replace(record)
|
66
66
|
if require_counter_update? && different_target?(record)
|
67
67
|
owner.instance_variable_set :@_after_replace_counter_called, true
|
68
|
-
record.increment!(reflection.counter_cache_column)
|
68
|
+
record.increment!(reflection.counter_cache_column, touch: reflection.options[:touch])
|
69
69
|
decrement_counters
|
70
70
|
end
|
71
71
|
end
|
@@ -84,7 +84,8 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
84
84
|
else
|
85
85
|
klass = association.klass
|
86
86
|
end
|
87
|
-
|
87
|
+
primary_key = reflection.association_primary_key(klass)
|
88
|
+
old_record = klass.find_by(primary_key => old_foreign_id)
|
88
89
|
|
89
90
|
if old_record
|
90
91
|
if touch != true
|
@@ -204,12 +204,12 @@ module ActiveRecord
|
|
204
204
|
|
205
205
|
# Alias for `changed`
|
206
206
|
def changed_attribute_names_to_save
|
207
|
-
|
207
|
+
mutations_from_database.changed_attribute_names
|
208
208
|
end
|
209
209
|
|
210
210
|
# Alias for `changed_attributes`
|
211
211
|
def attributes_in_database
|
212
|
-
|
212
|
+
mutations_from_database.changed_values
|
213
213
|
end
|
214
214
|
|
215
215
|
def attribute_was(*)
|
@@ -8,6 +8,10 @@ module ActiveRecord
|
|
8
8
|
@deprecated_forced_changes = Set.new
|
9
9
|
end
|
10
10
|
|
11
|
+
def changed_attribute_names
|
12
|
+
attr_names.select { |attr_name| changed?(attr_name) }
|
13
|
+
end
|
14
|
+
|
11
15
|
def changed_values
|
12
16
|
attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
|
13
17
|
if changed?(attr_name)
|
@@ -20,7 +24,7 @@ module ActiveRecord
|
|
20
24
|
attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
|
21
25
|
change = change_to_attribute(attr_name)
|
22
26
|
if change
|
23
|
-
result
|
27
|
+
result.merge!(attr_name => change)
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -82,6 +86,10 @@ module ActiveRecord
|
|
82
86
|
class NullMutationTracker # :nodoc:
|
83
87
|
include Singleton
|
84
88
|
|
89
|
+
def changed_attribute_names(*)
|
90
|
+
[]
|
91
|
+
end
|
92
|
+
|
85
93
|
def changed_values(*)
|
86
94
|
{}
|
87
95
|
end
|
@@ -873,15 +873,25 @@ module ActiveRecord
|
|
873
873
|
end
|
874
874
|
|
875
875
|
def mismatched_foreign_key(message)
|
876
|
-
|
877
|
-
|
878
|
-
|
876
|
+
match = %r/
|
877
|
+
(?:CREATE|ALTER)\s+TABLE\s*(?:`?\w+`?\.)?`?(?<table>\w+)`?.+?
|
878
|
+
FOREIGN\s+KEY\s*\(`?(?<foreign_key>\w+)`?\)\s*
|
879
|
+
REFERENCES\s*(`?(?<target_table>\w+)`?)\s*\(`?(?<primary_key>\w+)`?\)
|
880
|
+
/xmi.match(message)
|
881
|
+
|
882
|
+
options = {
|
879
883
|
message: message,
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
884
|
+
}
|
885
|
+
|
886
|
+
if match
|
887
|
+
options[:table] = match[:table]
|
888
|
+
options[:foreign_key] = match[:foreign_key]
|
889
|
+
options[:target_table] = match[:target_table]
|
890
|
+
options[:primary_key] = match[:primary_key]
|
891
|
+
options[:primary_key_column] = column_for(match[:target_table], match[:primary_key])
|
892
|
+
end
|
893
|
+
|
894
|
+
MismatchedForeignKey.new(options)
|
885
895
|
end
|
886
896
|
|
887
897
|
def integer_to_sql(limit) # :nodoc:
|
@@ -31,7 +31,13 @@ module ActiveRecord
|
|
31
31
|
|
32
32
|
def cast(value)
|
33
33
|
if value.is_a?(::String)
|
34
|
-
value =
|
34
|
+
value = begin
|
35
|
+
@pg_decoder.decode(value)
|
36
|
+
rescue TypeError
|
37
|
+
# malformed array string is treated as [], will raise in PG 2.0 gem
|
38
|
+
# this keeps a consistent implementation
|
39
|
+
[]
|
40
|
+
end
|
35
41
|
end
|
36
42
|
type_cast_array(value, :cast)
|
37
43
|
end
|
@@ -64,6 +70,10 @@ module ActiveRecord
|
|
64
70
|
deserialize(raw_old_value) != new_value
|
65
71
|
end
|
66
72
|
|
73
|
+
def force_equality?(value)
|
74
|
+
value.is_a?(::Array)
|
75
|
+
end
|
76
|
+
|
67
77
|
private
|
68
78
|
|
69
79
|
def type_cast_array(value, method)
|
@@ -2,6 +2,14 @@
|
|
2
2
|
gem "pg", ">= 0.18", "< 2.0"
|
3
3
|
require "pg"
|
4
4
|
|
5
|
+
# Use async_exec instead of exec_params on pg versions before 1.1
|
6
|
+
class ::PG::Connection
|
7
|
+
unless self.public_method_defined?(:async_exec_params)
|
8
|
+
remove_method :exec_params
|
9
|
+
alias exec_params async_exec
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
5
13
|
require "active_record/connection_adapters/abstract_adapter"
|
6
14
|
require "active_record/connection_adapters/statement_pool"
|
7
15
|
require "active_record/connection_adapters/postgresql/column"
|
@@ -613,7 +621,7 @@ module ActiveRecord
|
|
613
621
|
type_casted_binds = type_casted_binds(binds)
|
614
622
|
log(sql, name, binds, type_casted_binds) do
|
615
623
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
616
|
-
@connection.
|
624
|
+
@connection.exec_params(sql, type_casted_binds)
|
617
625
|
end
|
618
626
|
end
|
619
627
|
end
|
@@ -7,7 +7,7 @@ require "active_record/connection_adapters/sqlite3/schema_definitions"
|
|
7
7
|
require "active_record/connection_adapters/sqlite3/schema_dumper"
|
8
8
|
require "active_record/connection_adapters/sqlite3/schema_statements"
|
9
9
|
|
10
|
-
gem "sqlite3", "~> 1.3.6"
|
10
|
+
gem "sqlite3", "~> 1.3", ">= 1.3.6"
|
11
11
|
require "sqlite3"
|
12
12
|
|
13
13
|
module ActiveRecord
|
@@ -45,8 +45,12 @@ module ActiveRecord
|
|
45
45
|
reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
|
46
46
|
counter_name = reflection.counter_cache_column
|
47
47
|
|
48
|
-
updates = { counter_name
|
49
|
-
|
48
|
+
updates = { counter_name => object.send(counter_association).count(:all) }
|
49
|
+
|
50
|
+
if touch
|
51
|
+
names = touch if touch != true
|
52
|
+
updates.merge!(touch_attributes_with_time(*names))
|
53
|
+
end
|
50
54
|
|
51
55
|
unscoped.where(primary_key => object.id).update_all(updates)
|
52
56
|
end
|
@@ -66,8 +70,8 @@ module ActiveRecord
|
|
66
70
|
# * +counters+ - A Hash containing the names of the fields
|
67
71
|
# to update as keys and the amount to update the field by as values.
|
68
72
|
# * <tt>:touch</tt> option - Touch timestamp columns when updating.
|
69
|
-
#
|
70
|
-
#
|
73
|
+
# If attribute names are passed, they are updated along with updated_at/on
|
74
|
+
# attributes.
|
71
75
|
#
|
72
76
|
# ==== Examples
|
73
77
|
#
|
@@ -105,7 +109,8 @@ module ActiveRecord
|
|
105
109
|
end
|
106
110
|
|
107
111
|
if touch
|
108
|
-
|
112
|
+
names = touch if touch != true
|
113
|
+
touch_updates = touch_attributes_with_time(*names)
|
109
114
|
updates << sanitize_sql_for_assignment(touch_updates) unless touch_updates.empty?
|
110
115
|
end
|
111
116
|
|
@@ -163,13 +168,6 @@ module ActiveRecord
|
|
163
168
|
def decrement_counter(counter_name, id, touch: nil)
|
164
169
|
update_counters(id, counter_name => -1, touch: touch)
|
165
170
|
end
|
166
|
-
|
167
|
-
private
|
168
|
-
def touch_updates(touch)
|
169
|
-
touch = timestamp_attributes_for_update_in_model if touch == true
|
170
|
-
touch_time = current_time_from_proper_timezone
|
171
|
-
Array(touch).map { |column| [ column, touch_time ] }.to_h
|
172
|
-
end
|
173
171
|
end
|
174
172
|
|
175
173
|
private
|
data/lib/active_record/errors.rb
CHANGED
@@ -115,16 +115,27 @@ module ActiveRecord
|
|
115
115
|
|
116
116
|
# Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
|
117
117
|
class MismatchedForeignKey < StatementInvalid
|
118
|
-
def initialize(
|
119
|
-
|
118
|
+
def initialize(
|
119
|
+
adapter = nil,
|
120
|
+
message: nil,
|
121
|
+
sql: nil,
|
122
|
+
binds: nil,
|
123
|
+
table: nil,
|
124
|
+
foreign_key: nil,
|
125
|
+
target_table: nil,
|
126
|
+
primary_key: nil,
|
127
|
+
primary_key_column: nil
|
128
|
+
)
|
120
129
|
if table
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
130
|
+
type = primary_key_column.bigint? ? :bigint : primary_key_column.type
|
131
|
+
msg = <<-EOM.squish
|
132
|
+
Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
|
133
|
+
which has type `#{primary_key_column.sql_type}`.
|
134
|
+
To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
|
135
|
+
(For example `t.#{type} :#{foreign_key}`).
|
125
136
|
EOM
|
126
137
|
else
|
127
|
-
msg = <<-EOM
|
138
|
+
msg = <<-EOM.squish
|
128
139
|
There is a mismatch between the foreign key and primary key column types.
|
129
140
|
Verify that the foreign key column type and the primary key of the associated table match types.
|
130
141
|
EOM
|
@@ -134,11 +145,6 @@ module ActiveRecord
|
|
134
145
|
end
|
135
146
|
super(msg)
|
136
147
|
end
|
137
|
-
|
138
|
-
private
|
139
|
-
def column_type(table, column)
|
140
|
-
@adapter.columns(table).detect { |c| c.name == column }.sql_type
|
141
|
-
end
|
142
148
|
end
|
143
149
|
|
144
150
|
# Raised when a record cannot be inserted or updated because it would violate a not null constraint.
|
@@ -381,7 +381,7 @@ module ActiveRecord
|
|
381
381
|
# default values when instantiating the Active Record object for this table.
|
382
382
|
def column_defaults
|
383
383
|
load_schema
|
384
|
-
_default_attributes.to_hash
|
384
|
+
_default_attributes.deep_dup.to_hash
|
385
385
|
end
|
386
386
|
|
387
387
|
def _default_attributes # :nodoc:
|
@@ -226,7 +226,8 @@ module ActiveRecord
|
|
226
226
|
def becomes(klass)
|
227
227
|
became = klass.new
|
228
228
|
became.instance_variable_set("@attributes", @attributes)
|
229
|
-
became.instance_variable_set("@mutation_tracker", @mutation_tracker
|
229
|
+
became.instance_variable_set("@mutation_tracker", @mutation_tracker ||= nil)
|
230
|
+
became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
|
230
231
|
became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
|
231
232
|
became.instance_variable_set("@new_record", new_record?)
|
232
233
|
became.instance_variable_set("@destroyed", destroyed?)
|
@@ -506,7 +507,7 @@ module ActiveRecord
|
|
506
507
|
end
|
507
508
|
|
508
509
|
attribute_names = timestamp_attributes_for_update_in_model
|
509
|
-
attribute_names.
|
510
|
+
attribute_names |= names.map(&:to_s)
|
510
511
|
|
511
512
|
unless attribute_names.empty?
|
512
513
|
affected_rows = _touch_row(attribute_names, time)
|
@@ -379,7 +379,7 @@ module ActiveRecord
|
|
379
379
|
|
380
380
|
case conditions
|
381
381
|
when Array, Hash
|
382
|
-
relation.where!(conditions)
|
382
|
+
relation.where!(conditions) unless conditions.empty?
|
383
383
|
else
|
384
384
|
relation.where!(primary_key => conditions) unless conditions == :none
|
385
385
|
end
|
@@ -429,7 +429,7 @@ module ActiveRecord
|
|
429
429
|
raise UnknownPrimaryKey.new(@klass) if primary_key.nil?
|
430
430
|
|
431
431
|
expects_array = ids.first.kind_of?(Array)
|
432
|
-
return
|
432
|
+
return [] if expects_array && ids.first.empty?
|
433
433
|
|
434
434
|
ids = ids.flatten.compact.uniq
|
435
435
|
|
@@ -95,7 +95,7 @@ module ActiveRecord
|
|
95
95
|
next
|
96
96
|
when value.is_a?(Relation)
|
97
97
|
binds += value.bound_attributes
|
98
|
-
when value.is_a?(Range) && !table.type(column_name).
|
98
|
+
when value.is_a?(Range) && !table.type(column_name).force_equality?(value)
|
99
99
|
first = value.begin
|
100
100
|
last = value.end
|
101
101
|
unless first.respond_to?(:infinite?) && first.infinite?
|
@@ -158,7 +158,7 @@ module ActiveRecord
|
|
158
158
|
return if table.associated_with?(column_name)
|
159
159
|
case value
|
160
160
|
when Array, Range
|
161
|
-
table.type(column_name).
|
161
|
+
table.type(column_name).force_equality?(value)
|
162
162
|
else
|
163
163
|
!value.nil? && handler_for(value).is_a?(BasicObjectHandler)
|
164
164
|
end
|
@@ -1079,7 +1079,7 @@ module ActiveRecord
|
|
1079
1079
|
end
|
1080
1080
|
o.split(",").map! do |s|
|
1081
1081
|
s.strip!
|
1082
|
-
s.gsub!(/\sasc\Z/i, " DESC") || s.gsub!(/\sdesc\Z/i, " ASC") || s
|
1082
|
+
s.gsub!(/\sasc\Z/i, " DESC") || s.gsub!(/\sdesc\Z/i, " ASC") || (s << " DESC")
|
1083
1083
|
end
|
1084
1084
|
else
|
1085
1085
|
o
|
@@ -120,7 +120,7 @@ module ActiveRecord
|
|
120
120
|
$stderr.puts "Database '#{configuration['database']}' already exists"
|
121
121
|
rescue Exception => error
|
122
122
|
$stderr.puts error
|
123
|
-
$stderr.puts "Couldn't create database
|
123
|
+
$stderr.puts "Couldn't create '#{configuration['database']}' database. Please check your configuration."
|
124
124
|
raise
|
125
125
|
end
|
126
126
|
|
@@ -53,6 +53,13 @@ module ActiveRecord
|
|
53
53
|
end
|
54
54
|
|
55
55
|
class_methods do
|
56
|
+
def touch_attributes_with_time(*names, time: nil)
|
57
|
+
attribute_names = timestamp_attributes_for_update_in_model
|
58
|
+
attribute_names |= names.map(&:to_s)
|
59
|
+
time ||= current_time_from_proper_timezone
|
60
|
+
attribute_names.each_with_object({}) { |attr_name, result| result[attr_name] = time }
|
61
|
+
end
|
62
|
+
|
56
63
|
private
|
57
64
|
def timestamp_attributes_for_create_in_model
|
58
65
|
timestamp_attributes_for_create.select { |c| column_names.include?(c) }
|
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.7.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: 2019-03-
|
11
|
+
date: 2019-03-22 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.7.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.7.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.7.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.7.rc1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: arel
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -320,8 +320,8 @@ homepage: http://rubyonrails.org
|
|
320
320
|
licenses:
|
321
321
|
- MIT
|
322
322
|
metadata:
|
323
|
-
source_code_uri: https://github.com/rails/rails/tree/v5.1.
|
324
|
-
changelog_uri: https://github.com/rails/rails/blob/v5.1.
|
323
|
+
source_code_uri: https://github.com/rails/rails/tree/v5.1.7.rc1/activerecord
|
324
|
+
changelog_uri: https://github.com/rails/rails/blob/v5.1.7.rc1/activerecord/CHANGELOG.md
|
325
325
|
post_install_message:
|
326
326
|
rdoc_options:
|
327
327
|
- "--main"
|
@@ -335,9 +335,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
335
335
|
version: 2.2.2
|
336
336
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
337
337
|
requirements:
|
338
|
-
- - "
|
338
|
+
- - ">"
|
339
339
|
- !ruby/object:Gem::Version
|
340
|
-
version:
|
340
|
+
version: 1.3.1
|
341
341
|
requirements: []
|
342
342
|
rubygems_version: 3.0.1
|
343
343
|
signing_key:
|