activerecord 7.0.0 → 7.0.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +357 -0
- data/MIT-LICENSE +1 -1
- data/lib/active_record/associations/collection_association.rb +1 -2
- data/lib/active_record/associations/collection_proxy.rb +2 -2
- data/lib/active_record/associations/has_many_association.rb +7 -4
- data/lib/active_record/associations/join_dependency.rb +17 -13
- data/lib/active_record/associations.rb +38 -17
- data/lib/active_record/attribute_methods/serialization.rb +34 -50
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -0
- data/lib/active_record/attribute_methods.rb +2 -2
- data/lib/active_record/autosave_association.rb +2 -2
- data/lib/active_record/base.rb +3 -3
- data/lib/active_record/coders/yaml_column.rb +10 -2
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +8 -4
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +12 -7
- data/lib/active_record/connection_adapters/abstract_adapter.rb +5 -5
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +10 -2
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +3 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +10 -3
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +6 -5
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +14 -14
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +35 -2
- data/lib/active_record/connection_handling.rb +2 -2
- data/lib/active_record/core.rb +3 -3
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -0
- data/lib/active_record/database_configurations.rb +1 -1
- data/lib/active_record/delegated_type.rb +1 -1
- data/lib/active_record/encryption/configurable.rb +9 -3
- data/lib/active_record/encryption/contexts.rb +3 -3
- data/lib/active_record/encryption/derived_secret_key_provider.rb +1 -1
- data/lib/active_record/encryption/deterministic_key_provider.rb +1 -1
- data/lib/active_record/encryption/encryptable_record.rb +2 -4
- data/lib/active_record/encryption/encrypted_attribute_type.rb +2 -2
- data/lib/active_record/encryption/encryptor.rb +7 -7
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +3 -3
- data/lib/active_record/encryption/extended_deterministic_queries.rb +28 -28
- data/lib/active_record/encryption/message.rb +1 -1
- data/lib/active_record/encryption/properties.rb +1 -1
- data/lib/active_record/encryption/scheme.rb +1 -1
- data/lib/active_record/enum.rb +1 -1
- data/lib/active_record/fixtures.rb +5 -5
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/integration.rb +2 -2
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +10 -5
- data/lib/active_record/middleware/database_selector.rb +13 -6
- data/lib/active_record/middleware/shard_selector.rb +4 -4
- data/lib/active_record/migration/command_recorder.rb +3 -3
- data/lib/active_record/migration/compatibility.rb +10 -7
- data/lib/active_record/migration.rb +6 -5
- data/lib/active_record/model_schema.rb +22 -10
- data/lib/active_record/persistence.rb +9 -8
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +22 -18
- data/lib/active_record/railties/databases.rake +16 -11
- data/lib/active_record/reflection.rb +7 -1
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +3 -2
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +46 -11
- data/lib/active_record/relation.rb +22 -6
- data/lib/active_record/sanitization.rb +6 -5
- data/lib/active_record/schema.rb +38 -23
- data/lib/active_record/schema_dumper.rb +15 -16
- data/lib/active_record/scoping/default.rb +5 -7
- data/lib/active_record/serialization.rb +5 -0
- data/lib/active_record/signed_id.rb +2 -2
- data/lib/active_record/store.rb +7 -2
- data/lib/active_record/tasks/database_tasks.rb +32 -23
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -2
- data/lib/active_record/test_fixtures.rb +12 -5
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/validations/associated.rb +3 -3
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +3 -3
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +15 -1
- metadata +13 -13
|
@@ -22,10 +22,8 @@ module ActiveRecord
|
|
|
22
22
|
def strict_loading_violation(event)
|
|
23
23
|
debug do
|
|
24
24
|
owner = event.payload[:owner]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
color("Strict loading violation: #{owner} is marked for strict loading. The #{association} association named :#{name} cannot be lazily loaded.", RED)
|
|
25
|
+
reflection = event.payload[:reflection]
|
|
26
|
+
color(reflection.strict_loading_violation_message(owner), RED)
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
|
|
@@ -51,7 +49,14 @@ module ActiveRecord
|
|
|
51
49
|
|
|
52
50
|
binds = []
|
|
53
51
|
payload[:binds].each_with_index do |attr, i|
|
|
54
|
-
attribute_name = attr.respond_to?(:name)
|
|
52
|
+
attribute_name = if attr.respond_to?(:name)
|
|
53
|
+
attr.name
|
|
54
|
+
elsif attr.respond_to?(:[]) && attr[i].respond_to?(:name)
|
|
55
|
+
attr[i].name
|
|
56
|
+
else
|
|
57
|
+
nil
|
|
58
|
+
end
|
|
59
|
+
|
|
55
60
|
filtered_params = filter(attribute_name, casted_params[i])
|
|
56
61
|
|
|
57
62
|
binds << render_bind(attr, filtered_params)
|
|
@@ -19,19 +19,22 @@ module ActiveRecord
|
|
|
19
19
|
# that informs the application when to read from a primary or read from a
|
|
20
20
|
# replica.
|
|
21
21
|
#
|
|
22
|
-
# To use the DatabaseSelector in your application with default settings
|
|
23
|
-
# the
|
|
22
|
+
# To use the DatabaseSelector in your application with default settings,
|
|
23
|
+
# run the provided generator.
|
|
24
24
|
#
|
|
25
|
-
#
|
|
26
|
-
# require "active_support/core_ext/integer/time"
|
|
25
|
+
# bin/rails g active_record:multi_db
|
|
27
26
|
#
|
|
28
|
-
#
|
|
27
|
+
# This will create a file named +config/initializers/multi_db.rb+ with the
|
|
28
|
+
# following contents:
|
|
29
|
+
#
|
|
30
|
+
# Rails.application.configure do
|
|
29
31
|
# config.active_record.database_selector = { delay: 2.seconds }
|
|
30
32
|
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
|
|
31
33
|
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
|
|
32
34
|
# end
|
|
33
35
|
#
|
|
34
|
-
#
|
|
36
|
+
# Alternatively you can set the options in your environment config or
|
|
37
|
+
# any other config file loaded on boot.
|
|
35
38
|
#
|
|
36
39
|
# The default behavior can be changed by setting the config options to a
|
|
37
40
|
# custom class:
|
|
@@ -39,6 +42,10 @@ module ActiveRecord
|
|
|
39
42
|
# config.active_record.database_selector = { delay: 2.seconds }
|
|
40
43
|
# config.active_record.database_resolver = MyResolver
|
|
41
44
|
# config.active_record.database_resolver_context = MyResolver::MySession
|
|
45
|
+
#
|
|
46
|
+
# Note: If you are using `rails new my_app --minimal` you will need to call
|
|
47
|
+
# `require "active_support/core_ext/integer/time"` to load the libraries
|
|
48
|
+
# for +Time+.
|
|
42
49
|
class DatabaseSelector
|
|
43
50
|
def initialize(app, resolver_klass = nil, context_klass = nil, options = {})
|
|
44
51
|
@app = app
|
|
@@ -7,11 +7,11 @@ module ActiveRecord
|
|
|
7
7
|
# shard to switch to and allows for applications to write custom strategies
|
|
8
8
|
# for swapping if needed.
|
|
9
9
|
#
|
|
10
|
-
# The ShardSelector takes a set of options (currently only
|
|
11
|
-
# that can be used by the middleware to alter behavior.
|
|
10
|
+
# The ShardSelector takes a set of options (currently only +lock+ is supported)
|
|
11
|
+
# that can be used by the middleware to alter behavior. +lock+ is
|
|
12
12
|
# true by default and will prohibit the request from switching shards once
|
|
13
|
-
# inside the block. If
|
|
14
|
-
# For tenant based sharding,
|
|
13
|
+
# inside the block. If +lock+ is false, then shard swapping will be allowed.
|
|
14
|
+
# For tenant based sharding, +lock+ should always be true to prevent application
|
|
15
15
|
# code from mistakenly switching between tenants.
|
|
16
16
|
#
|
|
17
17
|
# Options can be set in the config:
|
|
@@ -13,10 +13,10 @@ module ActiveRecord
|
|
|
13
13
|
# * add_reference
|
|
14
14
|
# * add_timestamps
|
|
15
15
|
# * change_column
|
|
16
|
-
# * change_column_default (must supply a
|
|
16
|
+
# * change_column_default (must supply a +:from+ and +:to+ option)
|
|
17
17
|
# * change_column_null
|
|
18
|
-
# * change_column_comment (must supply a
|
|
19
|
-
# * change_table_comment (must supply a
|
|
18
|
+
# * change_column_comment (must supply a +:from+ and +:to+ option)
|
|
19
|
+
# * change_table_comment (must supply a +:from+ and +:to+ option)
|
|
20
20
|
# * create_join_table
|
|
21
21
|
# * create_table
|
|
22
22
|
# * disable_extension
|
|
@@ -94,9 +94,8 @@ module ActiveRecord
|
|
|
94
94
|
|
|
95
95
|
module TableDefinition
|
|
96
96
|
def references(*args, **options)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
end
|
|
97
|
+
options[:_uses_legacy_reference_index_name] = true
|
|
98
|
+
super
|
|
100
99
|
end
|
|
101
100
|
alias :belongs_to :references
|
|
102
101
|
|
|
@@ -131,8 +130,12 @@ module ActiveRecord
|
|
|
131
130
|
end
|
|
132
131
|
|
|
133
132
|
def add_reference(table_name, ref_name, **options)
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
if connection.adapter_name == "SQLite"
|
|
134
|
+
options[:type] = :integer
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
options[:_uses_legacy_reference_index_name] = true
|
|
138
|
+
super
|
|
136
139
|
end
|
|
137
140
|
alias :add_belongs_to :add_reference
|
|
138
141
|
|
|
@@ -141,7 +144,7 @@ module ActiveRecord
|
|
|
141
144
|
class << t
|
|
142
145
|
prepend TableDefinition
|
|
143
146
|
end
|
|
144
|
-
|
|
147
|
+
super
|
|
145
148
|
end
|
|
146
149
|
end
|
|
147
150
|
|
|
@@ -206,7 +209,7 @@ module ActiveRecord
|
|
|
206
209
|
class << t
|
|
207
210
|
prepend TableDefinition
|
|
208
211
|
end
|
|
209
|
-
|
|
212
|
+
super
|
|
210
213
|
end
|
|
211
214
|
|
|
212
215
|
def command_recorder
|
|
@@ -326,7 +326,7 @@ module ActiveRecord
|
|
|
326
326
|
# details.
|
|
327
327
|
# * <tt>change_table(name, options)</tt>: Allows to make column alterations to
|
|
328
328
|
# the table called +name+. It makes the table object available to a block that
|
|
329
|
-
# can then add/remove columns, indexes or foreign keys to it.
|
|
329
|
+
# can then add/remove columns, indexes, or foreign keys to it.
|
|
330
330
|
# * <tt>rename_column(table_name, column_name, new_column_name)</tt>: Renames
|
|
331
331
|
# a column but keeps the type and content.
|
|
332
332
|
# * <tt>rename_index(table_name, old_name, new_name)</tt>: Renames an index.
|
|
@@ -576,7 +576,7 @@ module ActiveRecord
|
|
|
576
576
|
MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
|
|
577
577
|
|
|
578
578
|
# This class is used to verify that all migrations have been run before
|
|
579
|
-
# loading a web page if <tt>config.active_record.migration_error</tt> is set to
|
|
579
|
+
# loading a web page if <tt>config.active_record.migration_error</tt> is set to +:page_load+.
|
|
580
580
|
class CheckPending
|
|
581
581
|
def initialize(app, file_watcher: ActiveSupport::FileUpdateChecker)
|
|
582
582
|
@app = app
|
|
@@ -810,8 +810,9 @@ module ActiveRecord
|
|
|
810
810
|
|
|
811
811
|
# Runs the given migration classes.
|
|
812
812
|
# Last argument can specify options:
|
|
813
|
-
#
|
|
814
|
-
# -
|
|
813
|
+
#
|
|
814
|
+
# - +:direction+ - Default is +:up+.
|
|
815
|
+
# - +:revert+ - Default is +false+.
|
|
815
816
|
def run(*migration_classes)
|
|
816
817
|
opts = migration_classes.extract_options!
|
|
817
818
|
dir = opts[:direction] || :up
|
|
@@ -1001,7 +1002,7 @@ module ActiveRecord
|
|
|
1001
1002
|
# Determines the version number of the next migration.
|
|
1002
1003
|
def next_migration_number(number)
|
|
1003
1004
|
if ActiveRecord.timestamped_migrations
|
|
1004
|
-
[Time.now.utc.strftime("%Y%m%d%H%M%S")
|
|
1005
|
+
[Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
|
|
1005
1006
|
else
|
|
1006
1007
|
SchemaMigration.normalize_migration_number(number)
|
|
1007
1008
|
end
|
|
@@ -126,6 +126,27 @@ module ActiveRecord
|
|
|
126
126
|
# +:immutable_string+. This setting does not affect the behavior of
|
|
127
127
|
# <tt>attribute :foo, :string</tt>. Defaults to false.
|
|
128
128
|
|
|
129
|
+
##
|
|
130
|
+
# :singleton-method: inheritance_column
|
|
131
|
+
# :call-seq: inheritance_column
|
|
132
|
+
#
|
|
133
|
+
# The name of the table column which stores the class name on single-table
|
|
134
|
+
# inheritance situations.
|
|
135
|
+
#
|
|
136
|
+
# The default inheritance column name is +type+, which means it's a
|
|
137
|
+
# reserved word inside Active Record. To be able to use single-table
|
|
138
|
+
# inheritance with another column name, or to use the column +type+ in
|
|
139
|
+
# your own model for something else, you can set +inheritance_column+:
|
|
140
|
+
#
|
|
141
|
+
# self.inheritance_column = 'zoink'
|
|
142
|
+
|
|
143
|
+
##
|
|
144
|
+
# :singleton-method: inheritance_column=
|
|
145
|
+
# :call-seq: inheritance_column=(column)
|
|
146
|
+
#
|
|
147
|
+
# Defines the name of the table column which will store the class name on single-table
|
|
148
|
+
# inheritance situations.
|
|
149
|
+
|
|
129
150
|
included do
|
|
130
151
|
class_attribute :primary_key_prefix_type, instance_writer: false
|
|
131
152
|
class_attribute :table_name_prefix, instance_writer: false, default: ""
|
|
@@ -136,15 +157,6 @@ module ActiveRecord
|
|
|
136
157
|
class_attribute :implicit_order_column, instance_accessor: false
|
|
137
158
|
class_attribute :immutable_strings_by_default, instance_accessor: false
|
|
138
159
|
|
|
139
|
-
# Defines the name of the table column which will store the class name on single-table
|
|
140
|
-
# inheritance situations.
|
|
141
|
-
#
|
|
142
|
-
# The default inheritance column name is +type+, which means it's a
|
|
143
|
-
# reserved word inside Active Record. To be able to use single-table
|
|
144
|
-
# inheritance with another column name, or to use the column +type+ in
|
|
145
|
-
# your own model for something else, you can set +inheritance_column+:
|
|
146
|
-
#
|
|
147
|
-
# self.inheritance_column = 'zoink'
|
|
148
160
|
class_attribute :inheritance_column, instance_accessor: false, default: "type"
|
|
149
161
|
singleton_class.class_eval do
|
|
150
162
|
alias_method :_inheritance_column=, :inheritance_column=
|
|
@@ -617,7 +629,7 @@ module ActiveRecord
|
|
|
617
629
|
|
|
618
630
|
"#{full_table_name_prefix}#{contained}#{undecorated_table_name(model_name)}#{full_table_name_suffix}"
|
|
619
631
|
else
|
|
620
|
-
# STI subclasses always use their superclass' table.
|
|
632
|
+
# STI subclasses always use their superclass's table.
|
|
621
633
|
base_class.table_name
|
|
622
634
|
end
|
|
623
635
|
end
|
|
@@ -62,7 +62,7 @@ module ActiveRecord
|
|
|
62
62
|
# Active Record callbacks or validations. Though passed values
|
|
63
63
|
# go through Active Record's type casting and serialization.
|
|
64
64
|
#
|
|
65
|
-
# See
|
|
65
|
+
# See #insert_all for documentation.
|
|
66
66
|
def insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
|
|
67
67
|
insert_all([ attributes ], returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
|
|
68
68
|
end
|
|
@@ -79,7 +79,7 @@ module ActiveRecord
|
|
|
79
79
|
# duplicate rows are skipped.
|
|
80
80
|
# Override with <tt>:unique_by</tt> (see below).
|
|
81
81
|
#
|
|
82
|
-
# Returns an
|
|
82
|
+
# Returns an ActiveRecord::Result with its contents based on
|
|
83
83
|
# <tt>:returning</tt> (see below).
|
|
84
84
|
#
|
|
85
85
|
# ==== Options
|
|
@@ -151,7 +151,7 @@ module ActiveRecord
|
|
|
151
151
|
# Active Record callbacks or validations. Though passed values
|
|
152
152
|
# go through Active Record's type casting and serialization.
|
|
153
153
|
#
|
|
154
|
-
# See
|
|
154
|
+
# See #insert_all! for more.
|
|
155
155
|
def insert!(attributes, returning: nil, record_timestamps: nil)
|
|
156
156
|
insert_all!([ attributes ], returning: returning, record_timestamps: record_timestamps)
|
|
157
157
|
end
|
|
@@ -167,10 +167,9 @@ module ActiveRecord
|
|
|
167
167
|
# Raises <tt>ActiveRecord::RecordNotUnique</tt> if any rows violate a
|
|
168
168
|
# unique index on the table. In that case, no rows are inserted.
|
|
169
169
|
#
|
|
170
|
-
# To skip duplicate rows, see
|
|
171
|
-
# To replace them, see <tt>ActiveRecord::Persistence#upsert_all</tt>.
|
|
170
|
+
# To skip duplicate rows, see #insert_all. To replace them, see #upsert_all.
|
|
172
171
|
#
|
|
173
|
-
# Returns an
|
|
172
|
+
# Returns an ActiveRecord::Result with its contents based on
|
|
174
173
|
# <tt>:returning</tt> (see below).
|
|
175
174
|
#
|
|
176
175
|
# ==== Options
|
|
@@ -219,7 +218,7 @@ module ActiveRecord
|
|
|
219
218
|
# it trigger Active Record callbacks or validations. Though passed values
|
|
220
219
|
# go through Active Record's type casting and serialization.
|
|
221
220
|
#
|
|
222
|
-
# See
|
|
221
|
+
# See #upsert_all for documentation.
|
|
223
222
|
def upsert(attributes, on_duplicate: :update, returning: nil, unique_by: nil, record_timestamps: nil)
|
|
224
223
|
upsert_all([ attributes ], on_duplicate: on_duplicate, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
|
|
225
224
|
end
|
|
@@ -232,7 +231,7 @@ module ActiveRecord
|
|
|
232
231
|
# The +attributes+ parameter is an Array of Hashes. Every Hash determines
|
|
233
232
|
# the attributes for a single row and must have the same keys.
|
|
234
233
|
#
|
|
235
|
-
# Returns an
|
|
234
|
+
# Returns an ActiveRecord::Result with its contents based on
|
|
236
235
|
# <tt>:returning</tt> (see below).
|
|
237
236
|
#
|
|
238
237
|
# By default, +upsert_all+ will update all the columns that can be updated when
|
|
@@ -806,6 +805,7 @@ module ActiveRecord
|
|
|
806
805
|
def update_columns(attributes)
|
|
807
806
|
raise ActiveRecordError, "cannot update a new record" if new_record?
|
|
808
807
|
raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
|
|
808
|
+
_raise_readonly_record_error if readonly?
|
|
809
809
|
|
|
810
810
|
attributes = attributes.transform_keys do |key|
|
|
811
811
|
name = key.to_s
|
|
@@ -992,6 +992,7 @@ module ActiveRecord
|
|
|
992
992
|
#
|
|
993
993
|
def touch(*names, time: nil)
|
|
994
994
|
_raise_record_not_touched_error unless persisted?
|
|
995
|
+
_raise_readonly_record_error if readonly?
|
|
995
996
|
|
|
996
997
|
attribute_names = timestamp_attributes_for_update_in_model
|
|
997
998
|
attribute_names |= names.map! do |name|
|
|
@@ -39,7 +39,7 @@ module ActiveRecord
|
|
|
39
39
|
# Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
|
|
40
40
|
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "author"=>"Quentin"}>, ...]
|
|
41
41
|
#
|
|
42
|
-
# You can use the same string replacement techniques as you can with
|
|
42
|
+
# You can use the same string replacement techniques as you can with ActiveRecord::QueryMethods#where :
|
|
43
43
|
#
|
|
44
44
|
# Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
|
|
45
45
|
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
|
|
@@ -78,6 +78,12 @@ module ActiveRecord
|
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
+
initializer "active_record.postgresql_time_zone_aware_types" do
|
|
82
|
+
ActiveSupport.on_load(:active_record_postgresqladapter) do
|
|
83
|
+
ActiveRecord::Base.time_zone_aware_types << :timestamptz
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
81
87
|
initializer "active_record.logger" do
|
|
82
88
|
ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
|
|
83
89
|
end
|
|
@@ -94,22 +100,6 @@ module ActiveRecord
|
|
|
94
100
|
end
|
|
95
101
|
end
|
|
96
102
|
|
|
97
|
-
initializer "active_record.database_selector" do
|
|
98
|
-
if options = config.active_record.database_selector
|
|
99
|
-
resolver = config.active_record.database_resolver
|
|
100
|
-
operations = config.active_record.database_resolver_context
|
|
101
|
-
config.app_middleware.use ActiveRecord::Middleware::DatabaseSelector, resolver, operations, options
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
initializer "active_record.shard_selector" do
|
|
106
|
-
if resolver = config.active_record.shard_resolver
|
|
107
|
-
options = config.active_record.shard_selector || {}
|
|
108
|
-
|
|
109
|
-
config.app_middleware.use ActiveRecord::Middleware::ShardSelector, resolver, options
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
103
|
initializer "Check for cache versioning support" do
|
|
114
104
|
config.after_initialize do |app|
|
|
115
105
|
ActiveSupport.on_load(:active_record) do
|
|
@@ -360,9 +350,9 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
|
360
350
|
end
|
|
361
351
|
|
|
362
352
|
# Filtered params
|
|
363
|
-
ActiveSupport.on_load(:action_controller) do
|
|
353
|
+
ActiveSupport.on_load(:action_controller, run_once: true) do
|
|
364
354
|
if ActiveRecord::Encryption.config.add_to_filter_parameters
|
|
365
|
-
ActiveRecord::Encryption.
|
|
355
|
+
ActiveRecord::Encryption.install_auto_filtered_parameters_hook(app)
|
|
366
356
|
end
|
|
367
357
|
end
|
|
368
358
|
end
|
|
@@ -389,5 +379,19 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
|
389
379
|
end
|
|
390
380
|
end
|
|
391
381
|
end
|
|
382
|
+
|
|
383
|
+
initializer "active_record.unregister_current_scopes_on_unload" do |app|
|
|
384
|
+
config.after_initialize do
|
|
385
|
+
unless app.config.cache_classes
|
|
386
|
+
Rails.autoloaders.main.on_unload do |_cpath, value, _abspath|
|
|
387
|
+
# Conditions are written this way to be robust against custom
|
|
388
|
+
# implementations of value#is_a? or value#<.
|
|
389
|
+
if Class === value && ActiveRecord::Base > value
|
|
390
|
+
value.current_scope = nil
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
end
|
|
392
396
|
end
|
|
393
397
|
end
|
|
@@ -452,30 +452,32 @@ db_namespace = namespace :db do
|
|
|
452
452
|
end
|
|
453
453
|
|
|
454
454
|
namespace :schema do
|
|
455
|
-
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)"
|
|
455
|
+
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
|
|
456
456
|
task dump: :load_config do
|
|
457
457
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
|
458
458
|
if db_config.schema_dump
|
|
459
459
|
ActiveRecord::Base.establish_connection(db_config)
|
|
460
|
-
ActiveRecord
|
|
460
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
|
461
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
|
|
461
462
|
end
|
|
462
463
|
end
|
|
463
464
|
|
|
464
465
|
db_namespace["schema:dump"].reenable
|
|
465
466
|
end
|
|
466
467
|
|
|
467
|
-
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the database"
|
|
468
|
+
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the database"
|
|
468
469
|
task load: [:load_config, :check_protected_environments] do
|
|
469
470
|
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord.schema_format, ENV["SCHEMA"])
|
|
470
471
|
end
|
|
471
472
|
|
|
472
473
|
namespace :dump do
|
|
473
474
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
|
474
|
-
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) for #{name} database"
|
|
475
|
+
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) for #{name} database"
|
|
475
476
|
task name => :load_config do
|
|
476
477
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
|
|
477
478
|
ActiveRecord::Base.establish_connection(db_config)
|
|
478
|
-
ActiveRecord
|
|
479
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
|
480
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
|
|
479
481
|
db_namespace["schema:dump:#{name}"].reenable
|
|
480
482
|
end
|
|
481
483
|
end
|
|
@@ -483,11 +485,12 @@ db_namespace = namespace :db do
|
|
|
483
485
|
|
|
484
486
|
namespace :load do
|
|
485
487
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
|
486
|
-
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the #{name} database"
|
|
487
|
-
task name => :load_config do
|
|
488
|
+
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the #{name} database"
|
|
489
|
+
task name => [:load_config, :check_protected_environments] do
|
|
488
490
|
original_db_config = ActiveRecord::Base.connection_db_config
|
|
489
491
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
|
|
490
|
-
ActiveRecord
|
|
492
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
|
493
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
|
491
494
|
ensure
|
|
492
495
|
ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
|
|
493
496
|
end
|
|
@@ -545,12 +548,13 @@ db_namespace = namespace :db do
|
|
|
545
548
|
db_namespace["test:load_schema"].invoke
|
|
546
549
|
end
|
|
547
550
|
|
|
548
|
-
# desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `config.active_record.schema_format`)"
|
|
551
|
+
# desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
|
|
549
552
|
task load_schema: %w(db:test:purge) do
|
|
550
553
|
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
|
551
554
|
ActiveRecord::Schema.verbose = false
|
|
552
555
|
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
|
553
|
-
ActiveRecord
|
|
556
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
|
557
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
|
554
558
|
end
|
|
555
559
|
ensure
|
|
556
560
|
if should_reconnect
|
|
@@ -586,7 +590,8 @@ db_namespace = namespace :db do
|
|
|
586
590
|
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
|
587
591
|
ActiveRecord::Schema.verbose = false
|
|
588
592
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
|
|
589
|
-
ActiveRecord
|
|
593
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
|
594
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
|
590
595
|
ensure
|
|
591
596
|
if should_reconnect
|
|
592
597
|
ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
|
|
@@ -297,6 +297,12 @@ module ActiveRecord
|
|
|
297
297
|
options[:strict_loading]
|
|
298
298
|
end
|
|
299
299
|
|
|
300
|
+
def strict_loading_violation_message(owner)
|
|
301
|
+
message = +"`#{owner}` is marked for strict_loading."
|
|
302
|
+
message << " The #{polymorphic? ? "polymorphic association" : "#{klass} association"}"
|
|
303
|
+
message << " named `:#{name}` cannot be lazily loaded."
|
|
304
|
+
end
|
|
305
|
+
|
|
300
306
|
protected
|
|
301
307
|
def actual_source_reflection # FIXME: this is a horrible name
|
|
302
308
|
self
|
|
@@ -1031,7 +1037,7 @@ module ActiveRecord
|
|
|
1031
1037
|
end
|
|
1032
1038
|
|
|
1033
1039
|
def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
|
|
1034
|
-
scopes = @previous_reflection.join_scopes(table, predicate_builder, record) + super
|
|
1040
|
+
scopes = @previous_reflection.join_scopes(table, predicate_builder, klass, record) + super
|
|
1035
1041
|
scopes << build_scope(table, predicate_builder, klass).instance_exec(record, &source_type_scope)
|
|
1036
1042
|
end
|
|
1037
1043
|
|
|
@@ -37,7 +37,7 @@ module ActiveRecord
|
|
|
37
37
|
# * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
|
|
38
38
|
# * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
|
|
39
39
|
# an order is present in the relation.
|
|
40
|
-
# * <tt>:order</tt> - Specifies the primary key order (can be
|
|
40
|
+
# * <tt>:order</tt> - Specifies the primary key order (can be +:asc+ or +:desc+). Defaults to +:asc+.
|
|
41
41
|
#
|
|
42
42
|
# Limits are honored, and if present there is no requirement for the batch
|
|
43
43
|
# size: it can be less than, equal to, or greater than the limit.
|
|
@@ -102,7 +102,7 @@ module ActiveRecord
|
|
|
102
102
|
# * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
|
|
103
103
|
# * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
|
|
104
104
|
# an order is present in the relation.
|
|
105
|
-
# * <tt>:order</tt> - Specifies the primary key order (can be
|
|
105
|
+
# * <tt>:order</tt> - Specifies the primary key order (can be +:asc+ or +:desc+). Defaults to +:asc+.
|
|
106
106
|
#
|
|
107
107
|
# Limits are honored, and if present there is no requirement for the batch
|
|
108
108
|
# size: it can be less than, equal to, or greater than the limit.
|
|
@@ -167,7 +167,7 @@ module ActiveRecord
|
|
|
167
167
|
# * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
|
|
168
168
|
# * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
|
|
169
169
|
# an order is present in the relation.
|
|
170
|
-
# * <tt>:order</tt> - Specifies the primary key order (can be
|
|
170
|
+
# * <tt>:order</tt> - Specifies the primary key order (can be +:asc+ or +:desc+). Defaults to +:asc+.
|
|
171
171
|
#
|
|
172
172
|
# Limits are honored, and if present there is no requirement for the batch
|
|
173
173
|
# size, it can be less than, equal, or greater than the limit.
|
|
@@ -155,7 +155,7 @@ module ActiveRecord
|
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
# Use #pluck as a shortcut to select one or more attributes without
|
|
158
|
-
# loading
|
|
158
|
+
# loading an entire record object per row.
|
|
159
159
|
#
|
|
160
160
|
# Person.pluck(:name)
|
|
161
161
|
#
|
|
@@ -345,12 +345,13 @@ module ActiveRecord
|
|
|
345
345
|
column = aggregate_column(column_name)
|
|
346
346
|
column_alias = column_alias_for("#{operation} #{column_name.to_s.downcase}")
|
|
347
347
|
select_value = operation_over_aggregate_column(column, operation, distinct)
|
|
348
|
-
select_value.as(column_alias)
|
|
348
|
+
select_value.as(connection.quote_column_name(column_alias))
|
|
349
349
|
|
|
350
350
|
select_values = [select_value]
|
|
351
351
|
select_values += self.select_values unless having_clause.empty?
|
|
352
352
|
|
|
353
353
|
select_values.concat group_columns.map { |aliaz, field|
|
|
354
|
+
aliaz = connection.quote_column_name(aliaz)
|
|
354
355
|
if field.respond_to?(:as)
|
|
355
356
|
field.as(aliaz)
|
|
356
357
|
else
|
|
@@ -87,7 +87,7 @@ module ActiveRecord
|
|
|
87
87
|
|
|
88
88
|
delegate :to_xml, :encode_with, :length, :each, :join,
|
|
89
89
|
:[], :&, :|, :+, :-, :sample, :reverse, :rotate, :compact, :in_groups, :in_groups_of,
|
|
90
|
-
:to_sentence, :to_formatted_s, :as_json,
|
|
90
|
+
:to_sentence, :to_fs, :to_formatted_s, :as_json,
|
|
91
91
|
:shuffle, :split, :slice, :index, :rindex, to: :records
|
|
92
92
|
|
|
93
93
|
delegate :primary_key, :connection, to: :klass
|