activerecord 7.0.8.7 → 7.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +86 -0
- data/README.rdoc +1 -0
- data/lib/active_record/associations.rb +117 -117
- data/lib/active_record/attribute_methods/dirty.rb +12 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +7 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +0 -2
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +7 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +1 -1
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +5 -4
- data/lib/active_record/delegated_type.rb +3 -3
- data/lib/active_record/encryption/extended_deterministic_queries.rb +34 -62
- data/lib/active_record/fixtures.rb +12 -0
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/insert_all.rb +3 -3
- data/lib/active_record/middleware/database_selector.rb +1 -1
- data/lib/active_record/migration.rb +3 -2
- data/lib/active_record/model_schema.rb +5 -3
- data/lib/active_record/nested_attributes.rb +3 -3
- data/lib/active_record/railtie.rb +1 -1
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation.rb +1 -1
- data/lib/active_record/timestamp.rb +1 -1
- data/lib/arel/nodes/homogeneous_in.rb +1 -1
- metadata +10 -13
|
@@ -70,11 +70,13 @@ module ActiveRecord
|
|
|
70
70
|
#
|
|
71
71
|
# ==== Options
|
|
72
72
|
#
|
|
73
|
-
# +from+
|
|
74
|
-
#
|
|
73
|
+
# [+from+]
|
|
74
|
+
# When specified, this method will return false unless the original
|
|
75
|
+
# value is equal to the given value.
|
|
75
76
|
#
|
|
76
|
-
# +to+
|
|
77
|
-
#
|
|
77
|
+
# [+to+]
|
|
78
|
+
# When specified, this method will return false unless the value will be
|
|
79
|
+
# changed to the given value.
|
|
78
80
|
def saved_change_to_attribute?(attr_name, **options)
|
|
79
81
|
mutations_before_last_save.changed?(attr_name.to_s, **options)
|
|
80
82
|
end
|
|
@@ -120,11 +122,13 @@ module ActiveRecord
|
|
|
120
122
|
#
|
|
121
123
|
# ==== Options
|
|
122
124
|
#
|
|
123
|
-
# +from+
|
|
124
|
-
#
|
|
125
|
+
# [+from+]
|
|
126
|
+
# When specified, this method will return false unless the original
|
|
127
|
+
# value is equal to the given value.
|
|
125
128
|
#
|
|
126
|
-
# +to+
|
|
127
|
-
#
|
|
129
|
+
# [+to+]
|
|
130
|
+
# When specified, this method will return false unless the value will be
|
|
131
|
+
# changed to the given value.
|
|
128
132
|
def will_save_change_to_attribute?(attr_name, **options)
|
|
129
133
|
mutations_from_database.changed?(attr_name.to_s, **options)
|
|
130
134
|
end
|
|
@@ -448,8 +448,7 @@ module ActiveRecord
|
|
|
448
448
|
@available.num_waiting
|
|
449
449
|
end
|
|
450
450
|
|
|
451
|
-
#
|
|
452
|
-
# Example:
|
|
451
|
+
# Returns the connection pool's usage statistic.
|
|
453
452
|
#
|
|
454
453
|
# ActiveRecord::Base.connection_pool.stat # => { size: 15, connections: 1, busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 }
|
|
455
454
|
def stat
|
|
@@ -653,9 +652,14 @@ module ActiveRecord
|
|
|
653
652
|
alias_method :release, :remove_connection_from_thread_cache
|
|
654
653
|
|
|
655
654
|
def new_connection
|
|
656
|
-
Base.public_send(db_config.adapter_method, db_config.configuration_hash)
|
|
655
|
+
conn = Base.public_send(db_config.adapter_method, db_config.configuration_hash)
|
|
656
|
+
begin
|
|
657
657
|
conn.check_version
|
|
658
|
+
rescue
|
|
659
|
+
conn.disconnect!
|
|
660
|
+
raise
|
|
658
661
|
end
|
|
662
|
+
conn
|
|
659
663
|
end
|
|
660
664
|
|
|
661
665
|
# If the pool is not at a <tt>@size</tt> limit, establish new connection. Connecting
|
|
@@ -941,7 +941,6 @@ module ActiveRecord
|
|
|
941
941
|
# Adds a reference. The reference column is a bigint by default,
|
|
942
942
|
# the <tt>:type</tt> option can be used to specify a different type.
|
|
943
943
|
# Optionally adds a +_type+ column, if <tt>:polymorphic</tt> option is provided.
|
|
944
|
-
# #add_reference and #add_belongs_to are acceptable.
|
|
945
944
|
#
|
|
946
945
|
# The +options+ hash can include the following keys:
|
|
947
946
|
# [<tt>:type</tt>]
|
|
@@ -992,7 +991,6 @@ module ActiveRecord
|
|
|
992
991
|
alias :add_belongs_to :add_reference
|
|
993
992
|
|
|
994
993
|
# Removes the reference(s). Also removes a +type+ column if one exists.
|
|
995
|
-
# #remove_reference and #remove_belongs_to are acceptable.
|
|
996
994
|
#
|
|
997
995
|
# ====== Remove the reference
|
|
998
996
|
#
|
|
@@ -435,6 +435,13 @@ module ActiveRecord
|
|
|
435
435
|
expression = row["expression"]
|
|
436
436
|
expression = expression[1..-2] if expression.start_with?("(") && expression.end_with?(")")
|
|
437
437
|
expression = strip_whitespace_characters(expression)
|
|
438
|
+
|
|
439
|
+
unless mariadb?
|
|
440
|
+
# MySQL returns check constraints expression in an already escaped form.
|
|
441
|
+
# This leads to duplicate escaping later (e.g. when the expression is used in the SchemaDumper).
|
|
442
|
+
expression = expression.gsub("\\'", "'")
|
|
443
|
+
end
|
|
444
|
+
|
|
438
445
|
CheckConstraintDefinition.new(table_name, expression, options)
|
|
439
446
|
end
|
|
440
447
|
else
|
|
@@ -36,7 +36,7 @@ module ActiveRecord
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
if row[:Expression]
|
|
39
|
-
expression = row[:Expression]
|
|
39
|
+
expression = row[:Expression].gsub("\\'", "'")
|
|
40
40
|
expression = +"(#{expression})" unless expression.start_with?("(")
|
|
41
41
|
indexes.last[-2] << expression
|
|
42
42
|
indexes.last[-1][:expressions] ||= {}
|
|
@@ -181,6 +181,7 @@ module ActiveRecord
|
|
|
181
181
|
default, default_function = nil, default
|
|
182
182
|
elsif type_metadata.extra == "DEFAULT_GENERATED"
|
|
183
183
|
default = +"(#{default})" unless default.start_with?("(")
|
|
184
|
+
default = default.gsub("\\'", "'")
|
|
184
185
|
default, default_function = nil, default
|
|
185
186
|
elsif type_metadata.type == :text && default&.start_with?("'")
|
|
186
187
|
# strip and unescape quotes
|
|
@@ -27,9 +27,10 @@ module ActiveRecord
|
|
|
27
27
|
value = value.sub(/^\((.+)\)$/, '-\1') # (4)
|
|
28
28
|
case value
|
|
29
29
|
when /^-?\D*+[\d,]+\.\d{2}$/ # (1)
|
|
30
|
-
value.
|
|
30
|
+
value.delete!("^-0-9.")
|
|
31
31
|
when /^-?\D*+[\d.]+,\d{2}$/ # (2)
|
|
32
|
-
value.
|
|
32
|
+
value.delete!("^-0-9,")
|
|
33
|
+
value.tr!(",", ".")
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
super(value)
|
|
@@ -339,7 +339,7 @@ module ActiveRecord
|
|
|
339
339
|
JOIN pg_namespace nsp ON (t.relnamespace = nsp.oid)
|
|
340
340
|
WHERE t.oid = #{quote(quote_table_name(table))}::regclass
|
|
341
341
|
AND cons.contype = 'p'
|
|
342
|
-
AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate'
|
|
342
|
+
AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate|gen_random_uuid'
|
|
343
343
|
SQL
|
|
344
344
|
end
|
|
345
345
|
|
|
@@ -282,7 +282,7 @@ module ActiveRecord
|
|
|
282
282
|
|
|
283
283
|
attr_writer :connection_specification_name
|
|
284
284
|
|
|
285
|
-
#
|
|
285
|
+
# Returns the connection specification name from the current class or its parent.
|
|
286
286
|
def connection_specification_name
|
|
287
287
|
if !defined?(@connection_specification_name) || @connection_specification_name.nil?
|
|
288
288
|
return self == Base ? Base.name : superclass.connection_specification_name
|
data/lib/active_record/core.rb
CHANGED
|
@@ -14,9 +14,10 @@ module ActiveRecord
|
|
|
14
14
|
##
|
|
15
15
|
# :singleton-method:
|
|
16
16
|
#
|
|
17
|
-
# Accepts a logger conforming to the interface of Log4r
|
|
18
|
-
# passed on to any new database
|
|
19
|
-
#
|
|
17
|
+
# Accepts a logger conforming to the interface of Log4r or the default
|
|
18
|
+
# Ruby +Logger+ class, which is then passed on to any new database
|
|
19
|
+
# connections made. You can retrieve this logger by calling +logger+ on
|
|
20
|
+
# either an Active Record model class or an Active Record model instance.
|
|
20
21
|
class_attribute :logger, instance_writer: false
|
|
21
22
|
|
|
22
23
|
##
|
|
@@ -117,7 +118,7 @@ module ActiveRecord
|
|
|
117
118
|
The new connection handling does not support `connection_handlers`
|
|
118
119
|
getter and setter.
|
|
119
120
|
|
|
120
|
-
Read more about how to migrate at: https://guides.rubyonrails.org/active_record_multiple_databases.html#migrate-to-the-new-connection-handling
|
|
121
|
+
Read more about how to migrate at: https://guides.rubyonrails.org/v7.0/active_record_multiple_databases.html#migrate-to-the-new-connection-handling
|
|
121
122
|
MSG
|
|
122
123
|
else
|
|
123
124
|
raise NotImplementedError, "The new connection handling does not support multiple connection handlers."
|
|
@@ -102,14 +102,14 @@ module ActiveRecord
|
|
|
102
102
|
# You create a new record that uses delegated typing by creating the delegator and delegatee at the same time,
|
|
103
103
|
# like so:
|
|
104
104
|
#
|
|
105
|
-
# Entry.create! entryable: Comment.new(content: "Hello!"), creator: Current.user
|
|
105
|
+
# Entry.create! entryable: Comment.new(content: "Hello!"), creator: Current.user, account: Current.account
|
|
106
106
|
#
|
|
107
107
|
# If you need more complicated composition, or you need to perform dependent validation, you should build a factory
|
|
108
108
|
# method or class to take care of the complicated needs. This could be as simple as:
|
|
109
109
|
#
|
|
110
110
|
# class Entry < ApplicationRecord
|
|
111
|
-
# def self.create_with_comment(content, creator: Current.user)
|
|
112
|
-
# create! entryable: Comment.new(content: content), creator: creator
|
|
111
|
+
# def self.create_with_comment(content, creator: Current.user, account: Current.account)
|
|
112
|
+
# create! entryable: Comment.new(content: content), creator: creator, account: account
|
|
113
113
|
# end
|
|
114
114
|
# end
|
|
115
115
|
#
|
|
@@ -35,85 +35,71 @@ module ActiveRecord
|
|
|
35
35
|
ActiveRecord::Relation.prepend(RelationQueries)
|
|
36
36
|
ActiveRecord::Base.include(CoreQueries)
|
|
37
37
|
ActiveRecord::Encryption::EncryptedAttributeType.prepend(ExtendedEncryptableType)
|
|
38
|
-
Arel::Nodes::HomogeneousIn.prepend(InWithAdditionalValues)
|
|
39
38
|
end
|
|
40
39
|
|
|
41
|
-
module
|
|
42
|
-
|
|
40
|
+
module EncryptedQuery # :nodoc:
|
|
41
|
+
class << self
|
|
42
|
+
def process_arguments(owner, args, check_for_additional_values)
|
|
43
|
+
return args if owner.deterministic_encrypted_attributes&.empty?
|
|
43
44
|
|
|
44
|
-
private
|
|
45
|
-
def process_encrypted_query_arguments(args, check_for_additional_values)
|
|
46
45
|
if args.is_a?(Array) && (options = args.first).is_a?(Hash)
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
options = options.dup
|
|
47
|
+
args[0] = options
|
|
48
|
+
|
|
49
|
+
owner.deterministic_encrypted_attributes&.each do |attribute_name|
|
|
50
|
+
type = owner.type_for_attribute(attribute_name)
|
|
49
51
|
if !type.previous_types.empty? && value = options[attribute_name]
|
|
50
52
|
options[attribute_name] = process_encrypted_query_argument(value, check_for_additional_values, type)
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
end
|
|
56
|
+
|
|
57
|
+
args
|
|
54
58
|
end
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
each_value
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
private
|
|
61
|
+
def process_encrypted_query_argument(value, check_for_additional_values, type)
|
|
62
|
+
return value if check_for_additional_values && value.is_a?(Array) && value.last.is_a?(AdditionalValue)
|
|
63
|
+
|
|
64
|
+
case value
|
|
65
|
+
when String, Array
|
|
66
|
+
list = Array(value)
|
|
67
|
+
list + list.flat_map do |each_value|
|
|
68
|
+
if check_for_additional_values && each_value.is_a?(AdditionalValue)
|
|
69
|
+
each_value
|
|
70
|
+
else
|
|
71
|
+
additional_values_for(each_value, type)
|
|
72
|
+
end
|
|
67
73
|
end
|
|
74
|
+
else
|
|
75
|
+
value
|
|
68
76
|
end
|
|
69
|
-
else
|
|
70
|
-
value
|
|
71
77
|
end
|
|
72
|
-
end
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
def additional_values_for(value, type)
|
|
80
|
+
type.previous_types.collect do |additional_type|
|
|
81
|
+
AdditionalValue.new(value, additional_type)
|
|
82
|
+
end
|
|
77
83
|
end
|
|
78
|
-
|
|
84
|
+
end
|
|
79
85
|
end
|
|
80
86
|
|
|
81
87
|
module RelationQueries
|
|
82
|
-
include EncryptedQueryArgumentProcessor
|
|
83
|
-
|
|
84
88
|
def where(*args)
|
|
85
|
-
|
|
86
|
-
super
|
|
89
|
+
super(*EncryptedQuery.process_arguments(self, args, true))
|
|
87
90
|
end
|
|
88
91
|
|
|
89
92
|
def exists?(*args)
|
|
90
|
-
|
|
91
|
-
super
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def find_or_create_by(attributes, &block)
|
|
95
|
-
find_by(attributes.dup) || create(attributes, &block)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def find_or_create_by!(attributes, &block)
|
|
99
|
-
find_by(attributes.dup) || create!(attributes, &block)
|
|
93
|
+
super(*EncryptedQuery.process_arguments(self, args, true))
|
|
100
94
|
end
|
|
101
|
-
|
|
102
|
-
private
|
|
103
|
-
def process_encrypted_query_arguments_if_needed(args)
|
|
104
|
-
process_encrypted_query_arguments(args, true) unless self.deterministic_encrypted_attributes&.empty?
|
|
105
|
-
end
|
|
106
95
|
end
|
|
107
96
|
|
|
108
97
|
module CoreQueries
|
|
109
98
|
extend ActiveSupport::Concern
|
|
110
99
|
|
|
111
100
|
class_methods do
|
|
112
|
-
include EncryptedQueryArgumentProcessor
|
|
113
|
-
|
|
114
101
|
def find_by(*args)
|
|
115
|
-
|
|
116
|
-
super
|
|
102
|
+
super(*EncryptedQuery.process_arguments(self, args, false))
|
|
117
103
|
end
|
|
118
104
|
end
|
|
119
105
|
end
|
|
@@ -141,20 +127,6 @@ module ActiveRecord
|
|
|
141
127
|
end
|
|
142
128
|
end
|
|
143
129
|
end
|
|
144
|
-
|
|
145
|
-
module InWithAdditionalValues
|
|
146
|
-
def proc_for_binds
|
|
147
|
-
-> value { ActiveModel::Attribute.with_cast_value(attribute.name, value, encryption_aware_type_caster) }
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def encryption_aware_type_caster
|
|
151
|
-
if attribute.type_caster.is_a?(ActiveRecord::Encryption::EncryptedAttributeType)
|
|
152
|
-
attribute.type_caster.cast_type
|
|
153
|
-
else
|
|
154
|
-
attribute.type_caster
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
130
|
end
|
|
159
131
|
end
|
|
160
132
|
end
|
|
@@ -258,6 +258,8 @@ module ActiveRecord
|
|
|
258
258
|
# name: Reginald the Pirate
|
|
259
259
|
# monkey_id: 1
|
|
260
260
|
#
|
|
261
|
+
# <code></code>
|
|
262
|
+
#
|
|
261
263
|
# ### in monkeys.yml
|
|
262
264
|
#
|
|
263
265
|
# george:
|
|
@@ -275,6 +277,8 @@ module ActiveRecord
|
|
|
275
277
|
# name: Reginald the Pirate
|
|
276
278
|
# monkey: george
|
|
277
279
|
#
|
|
280
|
+
# <code></code>
|
|
281
|
+
#
|
|
278
282
|
# ### in monkeys.yml
|
|
279
283
|
#
|
|
280
284
|
# george:
|
|
@@ -296,6 +300,8 @@ module ActiveRecord
|
|
|
296
300
|
#
|
|
297
301
|
# belongs_to :eater, polymorphic: true
|
|
298
302
|
#
|
|
303
|
+
# <code></code>
|
|
304
|
+
#
|
|
299
305
|
# ### in fruits.yml
|
|
300
306
|
#
|
|
301
307
|
# apple:
|
|
@@ -321,6 +327,8 @@ module ActiveRecord
|
|
|
321
327
|
# id: 1
|
|
322
328
|
# name: George the Monkey
|
|
323
329
|
#
|
|
330
|
+
# <code></code>
|
|
331
|
+
#
|
|
324
332
|
# ### in fruits.yml
|
|
325
333
|
#
|
|
326
334
|
# apple:
|
|
@@ -335,6 +343,8 @@ module ActiveRecord
|
|
|
335
343
|
# id: 3
|
|
336
344
|
# name: grape
|
|
337
345
|
#
|
|
346
|
+
# <code></code>
|
|
347
|
+
#
|
|
338
348
|
# ### in fruits_monkeys.yml
|
|
339
349
|
#
|
|
340
350
|
# apple_george:
|
|
@@ -358,6 +368,8 @@ module ActiveRecord
|
|
|
358
368
|
# name: George the Monkey
|
|
359
369
|
# fruits: apple, orange, grape
|
|
360
370
|
#
|
|
371
|
+
# <code></code>
|
|
372
|
+
#
|
|
361
373
|
# ### in fruits.yml
|
|
362
374
|
#
|
|
363
375
|
# apple:
|
|
@@ -17,8 +17,6 @@ module ActiveRecord
|
|
|
17
17
|
disallow_raw_sql!(on_duplicate)
|
|
18
18
|
disallow_raw_sql!(returning)
|
|
19
19
|
|
|
20
|
-
configure_on_duplicate_update_logic
|
|
21
|
-
|
|
22
20
|
if model.scope_attributes?
|
|
23
21
|
@scope_attributes = model.scope_attributes
|
|
24
22
|
@keys |= @scope_attributes.keys
|
|
@@ -29,8 +27,8 @@ module ActiveRecord
|
|
|
29
27
|
@returning = false if @returning == []
|
|
30
28
|
|
|
31
29
|
@unique_by = find_unique_index_for(unique_by)
|
|
32
|
-
@on_duplicate = :skip if @on_duplicate == :update && updatable_columns.empty?
|
|
33
30
|
|
|
31
|
+
configure_on_duplicate_update_logic
|
|
34
32
|
ensure_valid_options_for_connection!
|
|
35
33
|
end
|
|
36
34
|
|
|
@@ -99,6 +97,8 @@ module ActiveRecord
|
|
|
99
97
|
elsif custom_update_sql_provided?
|
|
100
98
|
@update_sql = on_duplicate
|
|
101
99
|
@on_duplicate = :update
|
|
100
|
+
elsif @on_duplicate == :update && updatable_columns.empty?
|
|
101
|
+
@on_duplicate = :skip
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
|
|
@@ -22,7 +22,7 @@ module ActiveRecord
|
|
|
22
22
|
# To use the DatabaseSelector in your application with default settings,
|
|
23
23
|
# run the provided generator.
|
|
24
24
|
#
|
|
25
|
-
# bin/rails g active_record:multi_db
|
|
25
|
+
# $ bin/rails g active_record:multi_db
|
|
26
26
|
#
|
|
27
27
|
# This will create a file named +config/initializers/multi_db.rb+ with the
|
|
28
28
|
# following contents:
|
|
@@ -364,7 +364,8 @@ module ActiveRecord
|
|
|
364
364
|
# The Rails package has several tools to help create and apply migrations.
|
|
365
365
|
#
|
|
366
366
|
# To generate a new migration, you can use
|
|
367
|
-
#
|
|
367
|
+
#
|
|
368
|
+
# $ bin/rails generate migration MyNewMigration
|
|
368
369
|
#
|
|
369
370
|
# where MyNewMigration is the name of your migration. The generator will
|
|
370
371
|
# create an empty migration file <tt>timestamp_my_new_migration.rb</tt>
|
|
@@ -373,7 +374,7 @@ module ActiveRecord
|
|
|
373
374
|
#
|
|
374
375
|
# There is a special syntactic shortcut to generate migrations that add fields to a table.
|
|
375
376
|
#
|
|
376
|
-
# bin/rails generate migration add_fieldname_to_tablename fieldname:string
|
|
377
|
+
# $ bin/rails generate migration add_fieldname_to_tablename fieldname:string
|
|
377
378
|
#
|
|
378
379
|
# This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
|
|
379
380
|
# class AddFieldnameToTablename < ActiveRecord::Migration[7.0]
|
|
@@ -276,8 +276,10 @@ module ActiveRecord
|
|
|
276
276
|
|
|
277
277
|
# Computes the table name, (re)sets it internally, and returns it.
|
|
278
278
|
def reset_table_name # :nodoc:
|
|
279
|
-
self.table_name = if
|
|
280
|
-
|
|
279
|
+
self.table_name = if self == Base
|
|
280
|
+
nil
|
|
281
|
+
elsif abstract_class?
|
|
282
|
+
superclass.table_name
|
|
281
283
|
elsif superclass.abstract_class?
|
|
282
284
|
superclass.table_name || compute_table_name
|
|
283
285
|
else
|
|
@@ -457,7 +459,7 @@ module ActiveRecord
|
|
|
457
459
|
end
|
|
458
460
|
|
|
459
461
|
# Returns the column object for the named attribute.
|
|
460
|
-
# Returns an
|
|
462
|
+
# Returns an ActiveRecord::ConnectionAdapters::NullColumn if the
|
|
461
463
|
# named attribute does not exist.
|
|
462
464
|
#
|
|
463
465
|
# class Person < ActiveRecord::Base
|
|
@@ -289,7 +289,7 @@ module ActiveRecord
|
|
|
289
289
|
# [:allow_destroy]
|
|
290
290
|
# If true, destroys any members from the attributes hash with a
|
|
291
291
|
# <tt>_destroy</tt> key and a value that evaluates to +true+
|
|
292
|
-
# (e.g. 1, '1', true, or 'true'). This option is
|
|
292
|
+
# (e.g. 1, '1', true, or 'true'). This option is false by default.
|
|
293
293
|
# [:reject_if]
|
|
294
294
|
# Allows you to specify a Proc or a Symbol pointing to a method
|
|
295
295
|
# that checks whether a record should be built for a certain attribute
|
|
@@ -314,11 +314,11 @@ module ActiveRecord
|
|
|
314
314
|
# nested attributes are going to be used when an associated record already
|
|
315
315
|
# exists. In general, an existing record may either be updated with the
|
|
316
316
|
# new set of attribute values or be replaced by a wholly new record
|
|
317
|
-
# containing those values. By default the +:update_only+ option is
|
|
317
|
+
# containing those values. By default the +:update_only+ option is false
|
|
318
318
|
# and the nested attributes are used to update the existing record only
|
|
319
319
|
# if they include the record's <tt>:id</tt> value. Otherwise a new
|
|
320
320
|
# record will be instantiated and used to replace the existing one.
|
|
321
|
-
# However if the +:update_only+ option is
|
|
321
|
+
# However if the +:update_only+ option is true, the nested attributes
|
|
322
322
|
# are used to update the record's attributes always, regardless of
|
|
323
323
|
# whether the <tt>:id</tt> is present. The option is ignored for collection
|
|
324
324
|
# associations.
|
|
@@ -343,7 +343,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
|
343
343
|
end
|
|
344
344
|
|
|
345
345
|
ActiveSupport.on_load(:active_record_fixture_set) do
|
|
346
|
-
# Encrypt
|
|
346
|
+
# Encrypt Active Record fixtures
|
|
347
347
|
if ActiveRecord::Encryption.config.encrypt_fixtures
|
|
348
348
|
ActiveRecord::Fixture.prepend ActiveRecord::Encryption::EncryptedFixtures
|
|
349
349
|
end
|
|
@@ -90,7 +90,7 @@ module ActiveRecord
|
|
|
90
90
|
:to_sentence, :to_fs, :to_formatted_s, :as_json,
|
|
91
91
|
:shuffle, :split, :slice, :index, :rindex, to: :records
|
|
92
92
|
|
|
93
|
-
delegate :primary_key, :connection, to: :klass
|
|
93
|
+
delegate :primary_key, :connection, :transaction, to: :klass
|
|
94
94
|
|
|
95
95
|
module ClassSpecificRelation # :nodoc:
|
|
96
96
|
extend ActiveSupport::Concern
|
|
@@ -43,7 +43,7 @@ module ActiveRecord
|
|
|
43
43
|
def bind_attribute(name, value) # :nodoc:
|
|
44
44
|
if reflection = klass._reflect_on_association(name)
|
|
45
45
|
name = reflection.foreign_key
|
|
46
|
-
value = value.read_attribute(reflection.
|
|
46
|
+
value = value.read_attribute(reflection.association_primary_key) unless value.nil?
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
attr = table[name]
|
|
@@ -30,7 +30,7 @@ module ActiveRecord
|
|
|
30
30
|
#
|
|
31
31
|
# ActiveRecord::Base.time_zone_aware_types = [:datetime]
|
|
32
32
|
#
|
|
33
|
-
# You can also add database
|
|
33
|
+
# You can also add database-specific timezone aware types. For example, for PostgreSQL:
|
|
34
34
|
#
|
|
35
35
|
# ActiveRecord::Base.time_zone_aware_types += [:tsrange, :tstzrange]
|
|
36
36
|
#
|
|
@@ -56,7 +56,7 @@ module Arel # :nodoc: all
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def proc_for_binds
|
|
59
|
-
-> value { ActiveModel::Attribute.with_cast_value(attribute.name, value,
|
|
59
|
+
-> value { ActiveModel::Attribute.with_cast_value(attribute.name, value, ActiveModel::Type.default_value) }
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def fetch_attribute(&block)
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.0.
|
|
4
|
+
version: 7.0.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Heinemeier Hansson
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activesupport
|
|
@@ -16,28 +15,28 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - '='
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 7.0.
|
|
18
|
+
version: 7.0.9
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - '='
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 7.0.
|
|
25
|
+
version: 7.0.9
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: activemodel
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - '='
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 7.0.
|
|
32
|
+
version: 7.0.9
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - '='
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 7.0.
|
|
39
|
+
version: 7.0.9
|
|
41
40
|
description: Databases on Rails. Build a persistent domain model by mapping database
|
|
42
41
|
tables to Ruby classes. Strong conventions for associations, validations, aggregations,
|
|
43
42
|
migrations, and testing come baked-in.
|
|
@@ -434,12 +433,11 @@ licenses:
|
|
|
434
433
|
- MIT
|
|
435
434
|
metadata:
|
|
436
435
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
|
437
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.0.
|
|
438
|
-
documentation_uri: https://api.rubyonrails.org/v7.0.
|
|
436
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.0.9/activerecord/CHANGELOG.md
|
|
437
|
+
documentation_uri: https://api.rubyonrails.org/v7.0.9/
|
|
439
438
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
|
440
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.0.
|
|
439
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.0.9/activerecord
|
|
441
440
|
rubygems_mfa_required: 'true'
|
|
442
|
-
post_install_message:
|
|
443
441
|
rdoc_options:
|
|
444
442
|
- "--main"
|
|
445
443
|
- README.rdoc
|
|
@@ -456,8 +454,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
456
454
|
- !ruby/object:Gem::Version
|
|
457
455
|
version: '0'
|
|
458
456
|
requirements: []
|
|
459
|
-
rubygems_version: 3.
|
|
460
|
-
signing_key:
|
|
457
|
+
rubygems_version: 3.6.9
|
|
461
458
|
specification_version: 4
|
|
462
459
|
summary: Object-relational mapper framework (part of Rails).
|
|
463
460
|
test_files: []
|