activerecord 7.2.0.beta2 → 7.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -1
- data/lib/active_record/associations/association.rb +6 -0
- data/lib/active_record/associations/collection_association.rb +7 -3
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/nested_error.rb +1 -1
- data/lib/active_record/associations.rb +2 -264
- data/lib/active_record/attribute_methods/dirty.rb +1 -1
- data/lib/active_record/attribute_methods/read.rb +3 -3
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +8 -6
- data/lib/active_record/autosave_association.rb +3 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +27 -11
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/transaction.rb +67 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +8 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +5 -10
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +28 -10
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +3 -9
- data/lib/active_record/database_configurations/database_config.rb +4 -0
- data/lib/active_record/errors.rb +32 -11
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/railtie.rb +2 -3
- data/lib/active_record/railties/databases.rake +1 -1
- data/lib/active_record/relation/batches.rb +7 -1
- data/lib/active_record/relation/calculations.rb +1 -1
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +9 -3
- data/lib/active_record/relation/query_methods.rb +25 -13
- data/lib/active_record/signed_id.rb +9 -0
- data/lib/active_record/tasks/database_tasks.rb +19 -8
- data/lib/active_record/test_fixtures.rb +10 -3
- data/lib/active_record/timestamp.rb +1 -1
- data/lib/active_record/transaction.rb +56 -55
- data/lib/active_record/transactions.rb +1 -1
- data/lib/active_record.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +13 -12
@@ -173,7 +173,7 @@ module ActiveRecord
|
|
173
173
|
end # end
|
174
174
|
|
175
175
|
def #{method_name}=(value) # def includes_values=(value)
|
176
|
-
|
176
|
+
assert_modifiable! # assert_modifiable!
|
177
177
|
@values[:#{name}] = value # @values[:includes] = value
|
178
178
|
end # end
|
179
179
|
CODE
|
@@ -796,7 +796,7 @@ module ActiveRecord
|
|
796
796
|
if !VALID_UNSCOPING_VALUES.include?(scope)
|
797
797
|
raise ArgumentError, "Called unscope() with invalid unscoping argument ':#{scope}'. Valid arguments are :#{VALID_UNSCOPING_VALUES.to_a.join(", :")}."
|
798
798
|
end
|
799
|
-
|
799
|
+
assert_modifiable!
|
800
800
|
@values.delete(scope)
|
801
801
|
when Hash
|
802
802
|
scope.each do |key, target_value|
|
@@ -1705,8 +1705,8 @@ module ActiveRecord
|
|
1705
1705
|
)
|
1706
1706
|
end
|
1707
1707
|
|
1708
|
-
def
|
1709
|
-
raise
|
1708
|
+
def assert_modifiable!
|
1709
|
+
raise UnmodifiableRelation if @loaded || @arel
|
1710
1710
|
end
|
1711
1711
|
|
1712
1712
|
def build_arel(connection, aliases = nil)
|
@@ -2063,17 +2063,29 @@ module ActiveRecord
|
|
2063
2063
|
order_args.flat_map do |arg|
|
2064
2064
|
case arg
|
2065
2065
|
when String, Symbol
|
2066
|
-
arg
|
2066
|
+
extract_table_name_from(arg)
|
2067
2067
|
when Hash
|
2068
|
-
arg
|
2068
|
+
arg
|
2069
|
+
.map do |key, value|
|
2070
|
+
case value
|
2071
|
+
when Hash
|
2072
|
+
key.to_s
|
2073
|
+
else
|
2074
|
+
extract_table_name_from(key) if key.is_a?(String) || key.is_a?(Symbol)
|
2075
|
+
end
|
2076
|
+
end
|
2077
|
+
when Arel::Attribute
|
2078
|
+
arg.relation.name
|
2079
|
+
when Arel::Nodes::Ordering
|
2080
|
+
if arg.expr.is_a?(Arel::Attribute)
|
2081
|
+
arg.expr.relation.name
|
2082
|
+
end
|
2069
2083
|
end
|
2070
|
-
end.
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
.flat_map { |e| e.map { |k, v| k if v.is_a?(Hash) } }
|
2076
|
-
.compact
|
2084
|
+
end.compact
|
2085
|
+
end
|
2086
|
+
|
2087
|
+
def extract_table_name_from(string)
|
2088
|
+
string.match(/^\W?(\w+)\W?\./) && $1
|
2077
2089
|
end
|
2078
2090
|
|
2079
2091
|
def order_column(field)
|
@@ -106,7 +106,16 @@ module ActiveRecord
|
|
106
106
|
|
107
107
|
|
108
108
|
# Returns a signed id that's generated using a preconfigured +ActiveSupport::MessageVerifier+ instance.
|
109
|
+
#
|
109
110
|
# This signed id is tamper proof, so it's safe to send in an email or otherwise share with the outside world.
|
111
|
+
# However, as with any message signed with a +ActiveSupport::MessageVerifier+,
|
112
|
+
# {the signed id is not encrypted}[link:classes/ActiveSupport/MessageVerifier.html#class-ActiveSupport::MessageVerifier-label-Signing+is+not+encryption].
|
113
|
+
# It's just encoded and protected against tampering.
|
114
|
+
#
|
115
|
+
# This means that the ID can be decoded by anyone; however, if tampered with (so to point to a different ID),
|
116
|
+
# the cryptographic signature will no longer match, and the signed id will be considered invalid and return nil
|
117
|
+
# when passed to +find_signed+ (or raise with +find_signed!+).
|
118
|
+
#
|
110
119
|
# It can furthermore be set to expire (the default is not to expire), and scoped down with a specific purpose.
|
111
120
|
# If the expiration date has been exceeded before +find_signed+ is called, the id won't find the designated
|
112
121
|
# record. If a purpose is set, this too must match.
|
@@ -192,9 +192,17 @@ module ActiveRecord
|
|
192
192
|
|
193
193
|
seed = true
|
194
194
|
end
|
195
|
+
end
|
196
|
+
end
|
195
197
|
|
196
|
-
|
197
|
-
|
198
|
+
each_current_environment(env) do |environment|
|
199
|
+
db_configs_with_versions(environment).sort.each do |version, db_configs|
|
200
|
+
db_configs.each do |db_config|
|
201
|
+
with_temporary_pool(db_config) do
|
202
|
+
migrate(version)
|
203
|
+
dump_schema(db_config) if ActiveRecord.dump_schema_after_migration
|
204
|
+
end
|
205
|
+
end
|
198
206
|
end
|
199
207
|
end
|
200
208
|
|
@@ -255,10 +263,10 @@ module ActiveRecord
|
|
255
263
|
Migration.verbose = verbose_was
|
256
264
|
end
|
257
265
|
|
258
|
-
def db_configs_with_versions # :nodoc:
|
266
|
+
def db_configs_with_versions(environment = env) # :nodoc:
|
259
267
|
db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
|
260
268
|
|
261
|
-
with_temporary_pool_for_each do |pool|
|
269
|
+
with_temporary_pool_for_each(env: environment) do |pool|
|
262
270
|
db_config = pool.db_config
|
263
271
|
versions_to_run = pool.migration_context.pending_migration_versions
|
264
272
|
target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
|
@@ -580,10 +588,7 @@ module ActiveRecord
|
|
580
588
|
end
|
581
589
|
|
582
590
|
def each_current_configuration(environment, name = nil)
|
583
|
-
|
584
|
-
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
585
|
-
|
586
|
-
environments.each do |env|
|
591
|
+
each_current_environment(environment) do |env|
|
587
592
|
configs_for(env_name: env).each do |db_config|
|
588
593
|
next if name && name != db_config.name
|
589
594
|
|
@@ -592,6 +597,12 @@ module ActiveRecord
|
|
592
597
|
end
|
593
598
|
end
|
594
599
|
|
600
|
+
def each_current_environment(environment, &block)
|
601
|
+
environments = [environment]
|
602
|
+
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
603
|
+
environments.each(&block)
|
604
|
+
end
|
605
|
+
|
595
606
|
def each_local_configuration
|
596
607
|
configs_for.each do |db_config|
|
597
608
|
next unless db_config.database
|
@@ -96,6 +96,14 @@ module ActiveRecord
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
+
# Generic fixture accessor for fixture names that may conflict with other methods.
|
100
|
+
#
|
101
|
+
# assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
|
102
|
+
# assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
|
103
|
+
def fixture(fixture_set_name, *fixture_names)
|
104
|
+
active_record_fixture(fixture_set_name, *fixture_names)
|
105
|
+
end
|
106
|
+
|
99
107
|
private
|
100
108
|
def run_in_transaction?
|
101
109
|
use_transactional_tests &&
|
@@ -255,7 +263,7 @@ module ActiveRecord
|
|
255
263
|
|
256
264
|
def method_missing(method, ...)
|
257
265
|
if fixture_sets.key?(method.name)
|
258
|
-
|
266
|
+
active_record_fixture(method, ...)
|
259
267
|
else
|
260
268
|
super
|
261
269
|
end
|
@@ -269,14 +277,13 @@ module ActiveRecord
|
|
269
277
|
end
|
270
278
|
end
|
271
279
|
|
272
|
-
def
|
280
|
+
def active_record_fixture(fixture_set_name, *fixture_names)
|
273
281
|
if fs_name = fixture_sets[fixture_set_name.name]
|
274
282
|
access_fixture(fs_name, *fixture_names)
|
275
283
|
else
|
276
284
|
raise StandardError, "No fixture set named '#{fixture_set_name.inspect}'"
|
277
285
|
end
|
278
286
|
end
|
279
|
-
alias_method :fixture, :_active_record_fixture
|
280
287
|
|
281
288
|
def access_fixture(fs_name, *fixture_names)
|
282
289
|
force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
|
@@ -162,7 +162,7 @@ module ActiveRecord
|
|
162
162
|
|
163
163
|
def max_updated_column_timestamp
|
164
164
|
timestamp_attributes_for_update_in_model
|
165
|
-
.filter_map { |attr| self[attr]
|
165
|
+
.filter_map { |attr| (v = self[attr]) && (v.is_a?(::Time) ? v : v.to_time) }
|
166
166
|
.max
|
167
167
|
end
|
168
168
|
|
@@ -3,9 +3,30 @@
|
|
3
3
|
require "active_support/core_ext/digest"
|
4
4
|
|
5
5
|
module ActiveRecord
|
6
|
-
#
|
6
|
+
# Class specifies the interface to interact with the current transaction state.
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# It can either map to an actual transaction/savepoint, or represent the
|
9
|
+
# absence of a transaction.
|
10
|
+
#
|
11
|
+
# == State
|
12
|
+
#
|
13
|
+
# We say that a transaction is _finalized_ when it wraps a real transaction
|
14
|
+
# that has been either committed or rolled back.
|
15
|
+
#
|
16
|
+
# A transaction is _open_ if it wraps a real transaction that is not finalized.
|
17
|
+
#
|
18
|
+
# On the other hand, a transaction is _closed_ when it is not open. That is,
|
19
|
+
# when it represents absence of transaction, or it wraps a real but finalized
|
20
|
+
# one.
|
21
|
+
#
|
22
|
+
# You can check whether a transaction is open or closed with the +open?+ and
|
23
|
+
# +closed?+ predicates:
|
24
|
+
#
|
25
|
+
# if Article.current_transaction.open?
|
26
|
+
# # We are inside a real and not finalized transaction.
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Closed transactions are `blank?` too.
|
9
30
|
#
|
10
31
|
# == Callbacks
|
11
32
|
#
|
@@ -42,90 +63,70 @@ module ActiveRecord
|
|
42
63
|
# == Caveats
|
43
64
|
#
|
44
65
|
# When using after_commit callbacks, it is important to note that if the callback raises an error, the transaction
|
45
|
-
# won't be rolled back. Relying solely on these to synchronize state between multiple
|
66
|
+
# won't be rolled back as it was already committed. Relying solely on these to synchronize state between multiple
|
67
|
+
# systems may lead to consistency issues.
|
46
68
|
class Transaction
|
47
|
-
|
48
|
-
|
49
|
-
@event = event
|
50
|
-
@callback = callback
|
51
|
-
end
|
52
|
-
|
53
|
-
def before_commit
|
54
|
-
@callback.call if @event == :before_commit
|
55
|
-
end
|
56
|
-
|
57
|
-
def after_commit
|
58
|
-
@callback.call if @event == :after_commit
|
59
|
-
end
|
60
|
-
|
61
|
-
def after_rollback
|
62
|
-
@callback.call if @event == :after_rollback
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def initialize # :nodoc:
|
67
|
-
@callbacks = nil
|
69
|
+
def initialize(internal_transaction) # :nodoc:
|
70
|
+
@internal_transaction = internal_transaction
|
68
71
|
@uuid = nil
|
69
72
|
end
|
70
73
|
|
71
|
-
# Registers a block to be called
|
72
|
-
#
|
73
|
-
# If there is no currently open transactions, the block is called immediately.
|
74
|
-
#
|
75
|
-
# If the current transaction has a parent transaction, the callback is transferred to
|
76
|
-
# the parent when the current transaction commits, or dropped when the current transaction
|
77
|
-
# is rolled back. This operation is repeated until the outermost transaction is reached.
|
78
|
-
#
|
79
|
-
# If the callback raises an error, the transaction is rolled back.
|
80
|
-
def before_commit(&block)
|
81
|
-
(@callbacks ||= []) << Callback.new(:before_commit, block)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Registers a block to be called after the current transaction is fully committed.
|
74
|
+
# Registers a block to be called after the transaction is fully committed.
|
85
75
|
#
|
86
|
-
# If there is no currently open transactions, the block is called
|
76
|
+
# If there is no currently open transactions, the block is called
|
77
|
+
# immediately, unless the transaction is finalized, in which case attempting
|
78
|
+
# to register the callback raises ActiveRecord::ActiveRecordError.
|
87
79
|
#
|
88
|
-
# If the
|
80
|
+
# If the transaction has a parent transaction, the callback is transferred to
|
89
81
|
# the parent when the current transaction commits, or dropped when the current transaction
|
90
82
|
# is rolled back. This operation is repeated until the outermost transaction is reached.
|
91
83
|
#
|
92
84
|
# If the callback raises an error, the transaction remains committed.
|
93
85
|
def after_commit(&block)
|
94
|
-
|
86
|
+
if @internal_transaction.nil?
|
87
|
+
yield
|
88
|
+
else
|
89
|
+
@internal_transaction.after_commit(&block)
|
90
|
+
end
|
95
91
|
end
|
96
92
|
|
97
|
-
# Registers a block to be called after the
|
93
|
+
# Registers a block to be called after the transaction is rolled back.
|
98
94
|
#
|
99
|
-
# If there is no currently open transactions, the block is
|
95
|
+
# If there is no currently open transactions, the block is not called. But
|
96
|
+
# if the transaction is finalized, attempting to register the callback
|
97
|
+
# raises ActiveRecord::ActiveRecordError.
|
100
98
|
#
|
101
|
-
# If the
|
99
|
+
# If the transaction is successfully committed but has a parent
|
102
100
|
# transaction, the callback is automatically added to the parent transaction.
|
103
101
|
#
|
104
102
|
# If the entire chain of nested transactions are all successfully committed,
|
105
103
|
# the block is never called.
|
104
|
+
#
|
105
|
+
# If the transaction is already finalized, attempting to register a callback
|
106
|
+
# will raise ActiveRecord::ActiveRecordError.
|
106
107
|
def after_rollback(&block)
|
107
|
-
|
108
|
+
@internal_transaction&.after_rollback(&block)
|
108
109
|
end
|
109
110
|
|
110
|
-
# Returns true if
|
111
|
+
# Returns true if the transaction exists and isn't finalized yet.
|
111
112
|
def open?
|
112
|
-
|
113
|
+
!closed?
|
113
114
|
end
|
114
115
|
|
115
|
-
# Returns true if
|
116
|
+
# Returns true if the transaction doesn't exist or is finalized.
|
116
117
|
def closed?
|
117
|
-
|
118
|
+
@internal_transaction.nil? || @internal_transaction.state.finalized?
|
118
119
|
end
|
120
|
+
|
119
121
|
alias_method :blank?, :closed?
|
120
122
|
|
121
|
-
# Returns a UUID for this transaction.
|
123
|
+
# Returns a UUID for this transaction or +nil+ if no transaction is open.
|
122
124
|
def uuid
|
123
|
-
@
|
125
|
+
if @internal_transaction
|
126
|
+
@uuid ||= Digest::UUID.uuid_v4
|
127
|
+
end
|
124
128
|
end
|
125
129
|
|
126
|
-
|
127
|
-
def append_callbacks(callbacks) # :nodoc:
|
128
|
-
(@callbacks ||= []).concat(callbacks)
|
129
|
-
end
|
130
|
+
NULL_TRANSACTION = new(nil).freeze
|
130
131
|
end
|
131
132
|
end
|
@@ -243,7 +243,7 @@ module ActiveRecord
|
|
243
243
|
#
|
244
244
|
# See the ActiveRecord::Transaction documentation for detailed behavior.
|
245
245
|
def current_transaction
|
246
|
-
connection_pool.active_connection&.current_transaction ||
|
246
|
+
connection_pool.active_connection&.current_transaction&.user_transaction || Transaction::NULL_TRANSACTION
|
247
247
|
end
|
248
248
|
|
249
249
|
def before_commit(*args, &block) # :nodoc:
|
data/lib/active_record.rb
CHANGED
@@ -290,7 +290,7 @@ module ActiveRecord
|
|
290
290
|
# with the global thread pool async query executor.
|
291
291
|
def self.global_executor_concurrency=(global_executor_concurrency)
|
292
292
|
if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
|
293
|
-
raise ArgumentError, "`global_executor_concurrency` cannot be set when
|
293
|
+
raise ArgumentError, "`global_executor_concurrency` cannot be set when the executor is nil or set to `:multi_thread_pool`. For multiple thread pools, please set the concurrency in your database configuration."
|
294
294
|
end
|
295
295
|
|
296
296
|
@global_executor_concurrency = global_executor_concurrency
|
@@ -12,7 +12,10 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
12
12
|
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
|
13
13
|
<% end -%>
|
14
14
|
<% end -%>
|
15
|
-
<%
|
15
|
+
<% unless attributes.empty? -%>
|
16
|
+
|
17
|
+
<% end -%>
|
18
|
+
<% if options[:timestamps] -%>
|
16
19
|
t.timestamps
|
17
20
|
<% end -%>
|
18
21
|
end
|
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: 7.2.0.
|
4
|
+
version: 7.2.0.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: 2024-06
|
11
|
+
date: 2024-08-06 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: 7.2.0.
|
19
|
+
version: 7.2.0.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: 7.2.0.
|
26
|
+
version: 7.2.0.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: 7.2.0.
|
33
|
+
version: 7.2.0.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: 7.2.0.
|
40
|
+
version: 7.2.0.rc1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: timeout
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- lib/active_record/associations/collection_association.rb
|
86
86
|
- lib/active_record/associations/collection_proxy.rb
|
87
87
|
- lib/active_record/associations/disable_joins_association_scope.rb
|
88
|
+
- lib/active_record/associations/errors.rb
|
88
89
|
- lib/active_record/associations/foreign_association.rb
|
89
90
|
- lib/active_record/associations/has_many_association.rb
|
90
91
|
- lib/active_record/associations/has_many_through_association.rb
|
@@ -475,10 +476,10 @@ licenses:
|
|
475
476
|
- MIT
|
476
477
|
metadata:
|
477
478
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
478
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.2.0.
|
479
|
-
documentation_uri: https://api.rubyonrails.org/v7.2.0.
|
479
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.2.0.rc1/activerecord/CHANGELOG.md
|
480
|
+
documentation_uri: https://api.rubyonrails.org/v7.2.0.rc1/
|
480
481
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
481
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.2.0.
|
482
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.2.0.rc1/activerecord
|
482
483
|
rubygems_mfa_required: 'true'
|
483
484
|
post_install_message:
|
484
485
|
rdoc_options:
|
@@ -493,11 +494,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
493
494
|
version: 3.1.0
|
494
495
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
495
496
|
requirements:
|
496
|
-
- - "
|
497
|
+
- - ">="
|
497
498
|
- !ruby/object:Gem::Version
|
498
|
-
version:
|
499
|
+
version: '0'
|
499
500
|
requirements: []
|
500
|
-
rubygems_version: 3.
|
501
|
+
rubygems_version: 3.5.11
|
501
502
|
signing_key:
|
502
503
|
specification_version: 4
|
503
504
|
summary: Object-relational mapper framework (part of Rails).
|