activerecord 5.2.0 → 5.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +214 -0
- data/lib/active_record/association_relation.rb +3 -3
- data/lib/active_record/associations.rb +9 -9
- data/lib/active_record/associations/alias_tracker.rb +1 -1
- data/lib/active_record/associations/association.rb +25 -10
- data/lib/active_record/associations/belongs_to_association.rb +14 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -1
- data/lib/active_record/associations/builder/belongs_to.rb +11 -2
- data/lib/active_record/associations/collection_association.rb +19 -15
- data/lib/active_record/associations/collection_proxy.rb +8 -34
- data/lib/active_record/associations/has_many_association.rb +9 -0
- data/lib/active_record/associations/has_many_through_association.rb +25 -1
- data/lib/active_record/associations/has_one_association.rb +8 -0
- data/lib/active_record/associations/has_one_through_association.rb +5 -1
- data/lib/active_record/associations/join_dependency.rb +39 -64
- data/lib/active_record/associations/join_dependency/join_association.rb +12 -18
- data/lib/active_record/associations/join_dependency/join_part.rb +7 -0
- data/lib/active_record/associations/singular_association.rb +4 -10
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_methods/dirty.rb +15 -10
- data/lib/active_record/attribute_methods/read.rb +1 -1
- data/lib/active_record/autosave_association.rb +7 -2
- data/lib/active_record/callbacks.rb +4 -0
- data/lib/active_record/collection_cache_key.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +14 -8
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +19 -6
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +7 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +5 -14
- data/lib/active_record/connection_adapters/abstract/transaction.rb +23 -14
- data/lib/active_record/connection_adapters/abstract_adapter.rb +3 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +18 -19
- data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -2
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +2 -2
- 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/schema_creation.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +12 -26
- data/lib/active_record/connection_adapters/postgresql/utils.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +9 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +5 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -4
- data/lib/active_record/core.rb +2 -1
- data/lib/active_record/counter_cache.rb +17 -13
- data/lib/active_record/enum.rb +1 -0
- data/lib/active_record/errors.rb +18 -12
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/migration/compatibility.rb +15 -15
- data/lib/active_record/model_schema.rb +1 -1
- data/lib/active_record/persistence.rb +6 -5
- data/lib/active_record/query_cache.rb +4 -11
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +1 -3
- data/lib/active_record/relation.rb +39 -20
- data/lib/active_record/relation/calculations.rb +11 -8
- data/lib/active_record/relation/delegation.rb +30 -0
- data/lib/active_record/relation/finder_methods.rb +10 -8
- data/lib/active_record/relation/merger.rb +10 -11
- data/lib/active_record/relation/predicate_builder.rb +20 -14
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/query_attribute.rb +5 -3
- data/lib/active_record/relation/query_methods.rb +45 -19
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/scoping/named.rb +2 -0
- data/lib/active_record/tasks/database_tasks.rb +1 -1
- data/lib/active_record/timestamp.rb +8 -1
- data/lib/active_record/transactions.rb +23 -20
- data/lib/active_record/type/serialized.rb +4 -0
- metadata +9 -10
@@ -319,7 +319,7 @@ module ActiveRecord
|
|
319
319
|
|
320
320
|
relation = construct_relation_for_exists(conditions)
|
321
321
|
|
322
|
-
skip_query_cache_if_necessary { connection.
|
322
|
+
skip_query_cache_if_necessary { connection.select_one(relation.arel, "#{name} Exists") } ? true : false
|
323
323
|
rescue ::RangeError
|
324
324
|
false
|
325
325
|
end
|
@@ -359,11 +359,15 @@ module ActiveRecord
|
|
359
359
|
end
|
360
360
|
|
361
361
|
def construct_relation_for_exists(conditions)
|
362
|
-
|
362
|
+
if distinct_value && offset_value
|
363
|
+
relation = limit(1)
|
364
|
+
else
|
365
|
+
relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
|
366
|
+
end
|
363
367
|
|
364
368
|
case conditions
|
365
369
|
when Array, Hash
|
366
|
-
relation.where!(conditions)
|
370
|
+
relation.where!(conditions) unless conditions.empty?
|
367
371
|
else
|
368
372
|
relation.where!(primary_key => conditions) unless conditions == :none
|
369
373
|
end
|
@@ -373,13 +377,12 @@ module ActiveRecord
|
|
373
377
|
|
374
378
|
def construct_join_dependency
|
375
379
|
including = eager_load_values + includes_values
|
376
|
-
joins = joins_values.select { |join| join.is_a?(Arel::Nodes::Join) }
|
377
380
|
ActiveRecord::Associations::JoinDependency.new(
|
378
|
-
klass, table, including
|
381
|
+
klass, table, including
|
379
382
|
)
|
380
383
|
end
|
381
384
|
|
382
|
-
def apply_join_dependency(eager_loading:
|
385
|
+
def apply_join_dependency(eager_loading: group_values.empty?)
|
383
386
|
join_dependency = construct_join_dependency
|
384
387
|
relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
|
385
388
|
|
@@ -392,7 +395,6 @@ module ActiveRecord
|
|
392
395
|
end
|
393
396
|
|
394
397
|
if block_given?
|
395
|
-
relation._select!(join_dependency.aliases.columns)
|
396
398
|
yield relation, join_dependency
|
397
399
|
else
|
398
400
|
relation
|
@@ -419,7 +421,7 @@ module ActiveRecord
|
|
419
421
|
raise UnknownPrimaryKey.new(@klass) if primary_key.nil?
|
420
422
|
|
421
423
|
expects_array = ids.first.kind_of?(Array)
|
422
|
-
return
|
424
|
+
return [] if expects_array && ids.first.empty?
|
423
425
|
|
424
426
|
ids = ids.flatten.compact.uniq
|
425
427
|
|
@@ -117,13 +117,11 @@ module ActiveRecord
|
|
117
117
|
if other.klass == relation.klass
|
118
118
|
relation.joins!(*other.joins_values)
|
119
119
|
else
|
120
|
-
alias_tracker = nil
|
121
120
|
joins_dependency = other.joins_values.map do |join|
|
122
121
|
case join
|
123
122
|
when Hash, Symbol, Array
|
124
|
-
alias_tracker ||= other.alias_tracker
|
125
123
|
ActiveRecord::Associations::JoinDependency.new(
|
126
|
-
other.klass, other.table, join
|
124
|
+
other.klass, other.table, join
|
127
125
|
)
|
128
126
|
else
|
129
127
|
join
|
@@ -140,13 +138,11 @@ module ActiveRecord
|
|
140
138
|
if other.klass == relation.klass
|
141
139
|
relation.left_outer_joins!(*other.left_outer_joins_values)
|
142
140
|
else
|
143
|
-
alias_tracker = nil
|
144
141
|
joins_dependency = other.left_outer_joins_values.map do |join|
|
145
142
|
case join
|
146
143
|
when Hash, Symbol, Array
|
147
|
-
alias_tracker ||= other.alias_tracker
|
148
144
|
ActiveRecord::Associations::JoinDependency.new(
|
149
|
-
other.klass, other.table, join
|
145
|
+
other.klass, other.table, join
|
150
146
|
)
|
151
147
|
else
|
152
148
|
join
|
@@ -160,10 +156,10 @@ module ActiveRecord
|
|
160
156
|
def merge_multi_values
|
161
157
|
if other.reordering_value
|
162
158
|
# override any order specified in the original relation
|
163
|
-
relation.reorder!
|
159
|
+
relation.reorder!(*other.order_values)
|
164
160
|
elsif other.order_values.any?
|
165
161
|
# merge in order_values from relation
|
166
|
-
relation.order!
|
162
|
+
relation.order!(*other.order_values)
|
167
163
|
end
|
168
164
|
|
169
165
|
extensions = other.extensions - relation.extensions
|
@@ -179,9 +175,7 @@ module ActiveRecord
|
|
179
175
|
end
|
180
176
|
|
181
177
|
def merge_clauses
|
182
|
-
|
183
|
-
relation.from_clause = other.from_clause
|
184
|
-
end
|
178
|
+
relation.from_clause = other.from_clause if replace_from_clause?
|
185
179
|
|
186
180
|
where_clause = relation.where_clause.merge(other.where_clause)
|
187
181
|
relation.where_clause = where_clause unless where_clause.empty?
|
@@ -189,6 +183,11 @@ module ActiveRecord
|
|
189
183
|
having_clause = relation.having_clause.merge(other.having_clause)
|
190
184
|
relation.having_clause = having_clause unless having_clause.empty?
|
191
185
|
end
|
186
|
+
|
187
|
+
def replace_from_clause?
|
188
|
+
relation.from_clause.empty? && !other.from_clause.empty? &&
|
189
|
+
relation.klass.base_class == other.klass.base_class
|
190
|
+
end
|
192
191
|
end
|
193
192
|
end
|
194
193
|
end
|
@@ -48,7 +48,12 @@ module ActiveRecord
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def build(attribute, value)
|
51
|
-
|
51
|
+
if table.type(attribute.name).force_equality?(value)
|
52
|
+
bind = build_bind_attribute(attribute.name, value)
|
53
|
+
attribute.eq(bind)
|
54
|
+
else
|
55
|
+
handler_for(value).call(attribute, value)
|
56
|
+
end
|
52
57
|
end
|
53
58
|
|
54
59
|
def build_bind_attribute(column_name, value)
|
@@ -88,20 +93,21 @@ module ActiveRecord
|
|
88
93
|
queries.reduce(&:or)
|
89
94
|
elsif table.aggregated_with?(key)
|
90
95
|
mapping = table.reflect_on_aggregation(key).mapping
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
values = value.nil? ? [nil] : Array.wrap(value)
|
97
|
+
if mapping.length == 1 || values.empty?
|
98
|
+
column_name, aggr_attr = mapping.first
|
99
|
+
values = values.map do |object|
|
100
|
+
object.respond_to?(aggr_attr) ? object.public_send(aggr_attr) : object
|
101
|
+
end
|
102
|
+
build(table.arel_attribute(column_name), values)
|
103
|
+
else
|
104
|
+
queries = values.map do |object|
|
105
|
+
mapping.map do |field_attr, aggregate_attr|
|
106
|
+
build(table.arel_attribute(field_attr), object.try!(aggregate_attr))
|
107
|
+
end.reduce(&:and)
|
108
|
+
end
|
109
|
+
queries.reduce(&:or)
|
99
110
|
end
|
100
|
-
queries.reduce(&:or)
|
101
|
-
# FIXME: Deprecate this and provide a public API to force equality
|
102
|
-
elsif (value.is_a?(Range) || value.is_a?(Array)) &&
|
103
|
-
table.type(key.to_s).respond_to?(:subtype)
|
104
|
-
BasicObjectHandler.new(self).call(table.arel_attribute(key), value)
|
105
111
|
else
|
106
112
|
build(table.arel_attribute(key), value)
|
107
113
|
end
|
@@ -19,10 +19,10 @@ module ActiveRecord
|
|
19
19
|
when 0 then NullPredicate
|
20
20
|
when 1 then predicate_builder.build(attribute, values.first)
|
21
21
|
else
|
22
|
-
|
22
|
+
values.map! do |v|
|
23
23
|
predicate_builder.build_bind_attribute(attribute.name, v)
|
24
24
|
end
|
25
|
-
attribute.in(
|
25
|
+
values.empty? ? NullPredicate : attribute.in(values)
|
26
26
|
end
|
27
27
|
|
28
28
|
unless nils.empty?
|
@@ -18,13 +18,15 @@ 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
|
end
|
24
26
|
|
25
27
|
def boundable?
|
26
28
|
return @_boundable if defined?(@_boundable)
|
27
|
-
|
29
|
+
value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
|
28
30
|
@_boundable = true
|
29
31
|
rescue ::RangeError
|
30
32
|
@_boundable = false
|
@@ -893,8 +893,8 @@ module ActiveRecord
|
|
893
893
|
self
|
894
894
|
end
|
895
895
|
|
896
|
-
def skip_query_cache! # :nodoc:
|
897
|
-
self.skip_query_cache_value =
|
896
|
+
def skip_query_cache!(value = true) # :nodoc:
|
897
|
+
self.skip_query_cache_value = value
|
898
898
|
self
|
899
899
|
end
|
900
900
|
|
@@ -903,11 +903,12 @@ module ActiveRecord
|
|
903
903
|
@arel ||= build_arel(aliases)
|
904
904
|
end
|
905
905
|
|
906
|
+
# Returns a relation value with a given name
|
907
|
+
def get_value(name) # :nodoc:
|
908
|
+
@values.fetch(name, DEFAULT_VALUES[name])
|
909
|
+
end
|
910
|
+
|
906
911
|
protected
|
907
|
-
# Returns a relation value with a given name
|
908
|
-
def get_value(name) # :nodoc:
|
909
|
-
@values.fetch(name, DEFAULT_VALUES[name])
|
910
|
-
end
|
911
912
|
|
912
913
|
# Sets the relation value with the given name
|
913
914
|
def set_value(name, value) # :nodoc:
|
@@ -1011,19 +1012,19 @@ module ActiveRecord
|
|
1011
1012
|
def build_join_query(manager, buckets, join_type, aliases)
|
1012
1013
|
buckets.default = []
|
1013
1014
|
|
1014
|
-
association_joins
|
1015
|
-
|
1016
|
-
join_nodes
|
1017
|
-
string_joins
|
1015
|
+
association_joins = buckets[:association_join]
|
1016
|
+
stashed_joins = buckets[:stashed_join]
|
1017
|
+
join_nodes = buckets[:join_node].uniq
|
1018
|
+
string_joins = buckets[:string_join].map(&:strip).uniq
|
1018
1019
|
|
1019
1020
|
join_list = join_nodes + convert_join_strings_to_ast(string_joins)
|
1020
1021
|
alias_tracker = alias_tracker(join_list, aliases)
|
1021
1022
|
|
1022
1023
|
join_dependency = ActiveRecord::Associations::JoinDependency.new(
|
1023
|
-
klass, table, association_joins
|
1024
|
+
klass, table, association_joins
|
1024
1025
|
)
|
1025
1026
|
|
1026
|
-
joins = join_dependency.join_constraints(
|
1027
|
+
joins = join_dependency.join_constraints(stashed_joins, join_type, alias_tracker)
|
1027
1028
|
joins.each { |join| manager.from(join) }
|
1028
1029
|
|
1029
1030
|
manager.join_sources.concat(join_list)
|
@@ -1049,17 +1050,36 @@ module ActiveRecord
|
|
1049
1050
|
end
|
1050
1051
|
|
1051
1052
|
def arel_columns(columns)
|
1052
|
-
columns.
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
connection.quote_table_name(field
|
1053
|
+
columns.flat_map do |field|
|
1054
|
+
case field
|
1055
|
+
when Symbol
|
1056
|
+
field = field.to_s
|
1057
|
+
arel_column(field) { connection.quote_table_name(field) }
|
1058
|
+
when String
|
1059
|
+
arel_column(field) { field }
|
1060
|
+
when Proc
|
1061
|
+
field.call
|
1057
1062
|
else
|
1058
1063
|
field
|
1059
1064
|
end
|
1060
1065
|
end
|
1061
1066
|
end
|
1062
1067
|
|
1068
|
+
def arel_column(field)
|
1069
|
+
field = klass.attribute_alias(field) if klass.attribute_alias?(field)
|
1070
|
+
from = from_clause.name || from_clause.value
|
1071
|
+
|
1072
|
+
if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
|
1073
|
+
arel_attribute(field)
|
1074
|
+
else
|
1075
|
+
yield
|
1076
|
+
end
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
def table_name_matches?(from)
|
1080
|
+
/(?:\A|(?<!FROM)\s)(?:\b#{table.name}\b|#{connection.quote_table_name(table.name)})(?!\.)/i.match?(from.to_s)
|
1081
|
+
end
|
1082
|
+
|
1063
1083
|
def reverse_sql_order(order_query)
|
1064
1084
|
if order_query.empty?
|
1065
1085
|
return [arel_attribute(primary_key).desc] if primary_key
|
@@ -1141,14 +1161,20 @@ module ActiveRecord
|
|
1141
1161
|
order_args.map! do |arg|
|
1142
1162
|
case arg
|
1143
1163
|
when Symbol
|
1144
|
-
|
1164
|
+
arg = arg.to_s
|
1165
|
+
arel_column(arg) {
|
1166
|
+
Arel.sql(connection.quote_table_name(arg))
|
1167
|
+
}.asc
|
1145
1168
|
when Hash
|
1146
1169
|
arg.map { |field, dir|
|
1147
1170
|
case field
|
1148
1171
|
when Arel::Nodes::SqlLiteral
|
1149
1172
|
field.send(dir.downcase)
|
1150
1173
|
else
|
1151
|
-
|
1174
|
+
field = field.to_s
|
1175
|
+
arel_column(field) {
|
1176
|
+
Arel.sql(connection.quote_table_name(field))
|
1177
|
+
}.send(dir.downcase)
|
1152
1178
|
end
|
1153
1179
|
}
|
1154
1180
|
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
|
-
clone
|
11
|
+
@delegate_to_klass ? 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.
|
@@ -122,7 +122,7 @@ module ActiveRecord
|
|
122
122
|
$stderr.puts "Database '#{configuration['database']}' already exists"
|
123
123
|
rescue Exception => error
|
124
124
|
$stderr.puts error
|
125
|
-
$stderr.puts "Couldn't create database
|
125
|
+
$stderr.puts "Couldn't create '#{configuration['database']}' database. Please check your configuration."
|
126
126
|
raise
|
127
127
|
end
|
128
128
|
|
@@ -52,7 +52,14 @@ module ActiveRecord
|
|
52
52
|
clear_timestamp_attributes
|
53
53
|
end
|
54
54
|
|
55
|
-
|
55
|
+
module ClassMethods # :nodoc:
|
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) }
|
@@ -340,11 +340,13 @@ module ActiveRecord
|
|
340
340
|
# Ensure that it is not called if the object was never persisted (failed create),
|
341
341
|
# but call it after the commit of a destroyed object.
|
342
342
|
def committed!(should_run_callbacks: true) #:nodoc:
|
343
|
-
if should_run_callbacks && destroyed? || persisted?
|
343
|
+
if should_run_callbacks && (destroyed? || persisted?)
|
344
|
+
@_committed_already_called = true
|
344
345
|
_run_commit_without_transaction_enrollment_callbacks
|
345
346
|
_run_commit_callbacks
|
346
347
|
end
|
347
348
|
ensure
|
349
|
+
@_committed_already_called = false
|
348
350
|
force_clear_transaction_record_state
|
349
351
|
end
|
350
352
|
|
@@ -382,13 +384,7 @@ module ActiveRecord
|
|
382
384
|
status = nil
|
383
385
|
self.class.transaction do
|
384
386
|
add_to_transaction
|
385
|
-
|
386
|
-
status = yield
|
387
|
-
rescue ActiveRecord::Rollback
|
388
|
-
clear_transaction_record_state
|
389
|
-
status = nil
|
390
|
-
end
|
391
|
-
|
387
|
+
status = yield
|
392
388
|
raise ActiveRecord::Rollback unless status
|
393
389
|
end
|
394
390
|
status
|
@@ -398,17 +394,29 @@ module ActiveRecord
|
|
398
394
|
end
|
399
395
|
end
|
400
396
|
|
397
|
+
protected
|
398
|
+
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
|
399
|
+
|
401
400
|
private
|
402
401
|
|
403
402
|
# Save the new record state and id of a record so it can be restored later if a transaction fails.
|
404
403
|
def remember_transaction_record_state
|
405
|
-
@_start_transaction_state[:id] = id
|
406
404
|
@_start_transaction_state.reverse_merge!(
|
405
|
+
id: id,
|
407
406
|
new_record: @new_record,
|
408
407
|
destroyed: @destroyed,
|
409
408
|
frozen?: frozen?,
|
410
409
|
)
|
411
410
|
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
|
411
|
+
remember_new_record_before_last_commit
|
412
|
+
end
|
413
|
+
|
414
|
+
def remember_new_record_before_last_commit
|
415
|
+
if _committed_already_called
|
416
|
+
@_new_record_before_last_commit = false
|
417
|
+
else
|
418
|
+
@_new_record_before_last_commit = @_start_transaction_state[:new_record]
|
419
|
+
end
|
412
420
|
end
|
413
421
|
|
414
422
|
# Clear the new record state and id of a record.
|
@@ -440,22 +448,16 @@ module ActiveRecord
|
|
440
448
|
end
|
441
449
|
end
|
442
450
|
|
443
|
-
# Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
|
444
|
-
def transaction_record_state(state)
|
445
|
-
@_start_transaction_state[state]
|
446
|
-
end
|
447
|
-
|
448
451
|
# Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
|
449
452
|
def transaction_include_any_action?(actions)
|
450
453
|
actions.any? do |action|
|
451
454
|
case action
|
452
455
|
when :create
|
453
|
-
|
454
|
-
when :destroy
|
455
|
-
defined?(@_trigger_destroy_callback) && @_trigger_destroy_callback
|
456
|
+
persisted? && @_new_record_before_last_commit
|
456
457
|
when :update
|
457
|
-
!(
|
458
|
-
|
458
|
+
!(@_new_record_before_last_commit || destroyed?) && _trigger_update_callback
|
459
|
+
when :destroy
|
460
|
+
_trigger_destroy_callback
|
459
461
|
end
|
460
462
|
end
|
461
463
|
end
|
@@ -491,7 +493,8 @@ module ActiveRecord
|
|
491
493
|
|
492
494
|
def update_attributes_from_transaction_state(transaction_state)
|
493
495
|
if transaction_state && transaction_state.finalized?
|
494
|
-
restore_transaction_record_state if transaction_state.rolledback?
|
496
|
+
restore_transaction_record_state(transaction_state.fully_rolledback?) if transaction_state.rolledback?
|
497
|
+
force_clear_transaction_record_state if transaction_state.fully_committed?
|
495
498
|
clear_transaction_record_state if transaction_state.fully_completed?
|
496
499
|
end
|
497
500
|
end
|