activerecord 7.0.0 → 7.1.0
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 +1607 -1040
- data/MIT-LICENSE +1 -1
- data/README.rdoc +17 -18
- data/lib/active_record/aggregations.rb +16 -13
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/association.rb +18 -3
- data/lib/active_record/associations/association_scope.rb +16 -9
- data/lib/active_record/associations/belongs_to_association.rb +14 -6
- data/lib/active_record/associations/builder/association.rb +3 -3
- data/lib/active_record/associations/builder/belongs_to.rb +21 -8
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +17 -12
- data/lib/active_record/associations/collection_proxy.rb +22 -12
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +27 -17
- data/lib/active_record/associations/has_many_through_association.rb +10 -6
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency.rb +20 -14
- data/lib/active_record/associations/preloader/association.rb +27 -6
- data/lib/active_record/associations/preloader/through_association.rb +1 -1
- data/lib/active_record/associations/preloader.rb +13 -10
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +22 -11
- data/lib/active_record/associations.rb +345 -219
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
- data/lib/active_record/attribute_methods/dirty.rb +40 -26
- data/lib/active_record/attribute_methods/primary_key.rb +76 -24
- data/lib/active_record/attribute_methods/query.rb +28 -16
- data/lib/active_record/attribute_methods/read.rb +18 -5
- data/lib/active_record/attribute_methods/serialization.rb +172 -69
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +110 -28
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +56 -10
- data/lib/active_record/base.rb +10 -5
- data/lib/active_record/callbacks.rb +16 -32
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -34
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +164 -89
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +63 -43
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +128 -32
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +60 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +52 -8
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +163 -29
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +302 -129
- data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
- data/lib/active_record/connection_adapters/abstract_adapter.rb +504 -106
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +217 -104
- data/lib/active_record/connection_adapters/column.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +23 -144
- data/lib/active_record/connection_adapters/mysql/quoting.rb +29 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +98 -53
- data/lib/active_record/connection_adapters/pool_config.rb +14 -5
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +72 -45
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +41 -8
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +6 -10
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +358 -57
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +343 -181
- data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +45 -39
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +22 -5
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +41 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +242 -81
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
- data/lib/active_record/connection_adapters.rb +3 -1
- data/lib/active_record/connection_handling.rb +73 -96
- data/lib/active_record/core.rb +136 -148
- data/lib/active_record/counter_cache.rb +46 -25
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -0
- data/lib/active_record/database_configurations/database_config.rb +9 -3
- data/lib/active_record/database_configurations/hash_config.rb +22 -12
- data/lib/active_record/database_configurations/url_config.rb +17 -11
- data/lib/active_record/database_configurations.rb +87 -34
- data/lib/active_record/delegated_type.rb +9 -4
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +2 -0
- data/lib/active_record/disable_joins_association_relation.rb +1 -1
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
- data/lib/active_record/encryption/config.rb +25 -1
- data/lib/active_record/encryption/configurable.rb +13 -14
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +8 -4
- data/lib/active_record/encryption/derived_secret_key_provider.rb +9 -3
- data/lib/active_record/encryption/deterministic_key_provider.rb +1 -1
- data/lib/active_record/encryption/encryptable_record.rb +38 -22
- data/lib/active_record/encryption/encrypted_attribute_type.rb +19 -8
- 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 +83 -71
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
- data/lib/active_record/encryption/key_generator.rb +12 -1
- data/lib/active_record/encryption/message.rb +1 -1
- data/lib/active_record/encryption/message_serializer.rb +2 -0
- data/lib/active_record/encryption/properties.rb +4 -4
- data/lib/active_record/encryption/scheme.rb +20 -23
- data/lib/active_record/encryption.rb +1 -0
- data/lib/active_record/enum.rb +114 -27
- data/lib/active_record/errors.rb +108 -15
- data/lib/active_record/explain.rb +23 -3
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +29 -8
- data/lib/active_record/fixtures.rb +121 -73
- data/lib/active_record/future_result.rb +30 -5
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/inheritance.rb +30 -16
- data/lib/active_record/insert_all.rb +55 -8
- data/lib/active_record/integration.rb +10 -10
- data/lib/active_record/internal_metadata.rb +118 -30
- data/lib/active_record/locking/optimistic.rb +32 -18
- data/lib/active_record/locking/pessimistic.rb +8 -5
- data/lib/active_record/log_subscriber.rb +39 -17
- data/lib/active_record/marshalling.rb +56 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
- data/lib/active_record/middleware/database_selector.rb +18 -13
- data/lib/active_record/middleware/shard_selector.rb +7 -5
- data/lib/active_record/migration/command_recorder.rb +104 -9
- data/lib/active_record/migration/compatibility.rb +158 -64
- data/lib/active_record/migration/default_strategy.rb +23 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration.rb +271 -117
- data/lib/active_record/model_schema.rb +82 -50
- data/lib/active_record/nested_attributes.rb +23 -3
- data/lib/active_record/normalization.rb +159 -0
- data/lib/active_record/persistence.rb +200 -47
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +3 -21
- data/lib/active_record/query_logs.rb +87 -51
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +16 -3
- data/lib/active_record/railtie.rb +127 -61
- data/lib/active_record/railties/controller_runtime.rb +12 -8
- data/lib/active_record/railties/databases.rake +142 -143
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +32 -5
- data/lib/active_record/reflection.rb +177 -45
- data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
- data/lib/active_record/relation/batches.rb +190 -61
- data/lib/active_record/relation/calculations.rb +200 -83
- data/lib/active_record/relation/delegation.rb +23 -9
- data/lib/active_record/relation/finder_methods.rb +77 -16
- data/lib/active_record/relation/merger.rb +2 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +26 -14
- data/lib/active_record/relation/query_attribute.rb +25 -1
- data/lib/active_record/relation/query_methods.rb +429 -76
- data/lib/active_record/relation/spawn_methods.rb +18 -1
- data/lib/active_record/relation.rb +98 -41
- data/lib/active_record/result.rb +25 -9
- data/lib/active_record/runtime_registry.rb +10 -1
- data/lib/active_record/sanitization.rb +57 -16
- data/lib/active_record/schema.rb +36 -22
- data/lib/active_record/schema_dumper.rb +65 -23
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +20 -12
- data/lib/active_record/scoping/named.rb +2 -2
- data/lib/active_record/scoping.rb +2 -1
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/serialization.rb +5 -0
- data/lib/active_record/signed_id.rb +9 -7
- data/lib/active_record/store.rb +16 -11
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +16 -3
- data/lib/active_record/tasks/database_tasks.rb +138 -107
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +17 -15
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_fixtures.rb +123 -99
- data/lib/active_record/timestamp.rb +26 -14
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +39 -13
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +8 -4
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +3 -3
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +50 -5
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +143 -16
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +1 -1
- data/lib/arel/nodes/and.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -1
- data/lib/arel/nodes/bound_sql_literal.rb +61 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/filter.rb +1 -1
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/homogeneous_in.rb +0 -8
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- data/lib/arel/nodes/sql_literal.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes.rb +4 -0
- data/lib/arel/predications.rb +2 -0
- data/lib/arel/table.rb +9 -5
- data/lib/arel/visitors/mysql.rb +8 -1
- data/lib/arel/visitors/to_sql.rb +81 -17
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +16 -2
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- metadata +50 -15
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -63
@@ -1,13 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/module/attribute_accessors_per_thread"
|
4
|
+
require "active_record/query_logs_formatter"
|
4
5
|
|
5
6
|
module ActiveRecord
|
6
7
|
# = Active Record Query Logs
|
7
8
|
#
|
8
|
-
# Automatically
|
9
|
+
# Automatically append comments to SQL queries with runtime information tags. This can be used to trace troublesome
|
10
|
+
# SQL statements back to the application code that generated these statements.
|
9
11
|
#
|
10
|
-
#
|
12
|
+
# Query logs can be enabled via \Rails configuration in <tt>config/application.rb</tt> or an initializer:
|
13
|
+
#
|
14
|
+
# config.active_record.query_log_tags_enabled = true
|
15
|
+
#
|
16
|
+
# By default the name of the application, the name and action of the controller, or the name of the job are logged.
|
17
|
+
# The default format is {SQLCommenter}[https://open-telemetry.github.io/opentelemetry-sqlcommenter/].
|
18
|
+
# The tags shown in a query comment can be configured via \Rails configuration:
|
19
|
+
#
|
20
|
+
# config.active_record.query_log_tags = [ :application, :controller, :action, :job ]
|
21
|
+
#
|
22
|
+
# Active Record defines default tags available for use:
|
11
23
|
#
|
12
24
|
# * +application+
|
13
25
|
# * +pid+
|
@@ -15,46 +27,40 @@ module ActiveRecord
|
|
15
27
|
# * +db_host+
|
16
28
|
# * +database+
|
17
29
|
#
|
18
|
-
#
|
30
|
+
# Action Controller adds default tags when loaded:
|
19
31
|
#
|
20
32
|
# * +controller+
|
21
33
|
# * +action+
|
22
|
-
# * +
|
23
|
-
#
|
24
|
-
# The tags used in a query can be configured directly:
|
34
|
+
# * +namespaced_controller+
|
25
35
|
#
|
26
|
-
#
|
36
|
+
# Active Job adds default tags when loaded:
|
27
37
|
#
|
28
|
-
#
|
38
|
+
# * +job+
|
29
39
|
#
|
30
|
-
#
|
40
|
+
# New comment tags can be defined by adding them in a +Hash+ to the tags +Array+. Tags can have dynamic content by
|
41
|
+
# setting a +Proc+ or lambda value in the +Hash+, and can reference any value stored by \Rails in the +context+ object.
|
42
|
+
# ActiveSupport::CurrentAttributes can be used to store application values. Tags with +nil+ values are
|
43
|
+
# omitted from the query comment.
|
31
44
|
#
|
32
|
-
#
|
33
|
-
# want to add to the comment. Dynamic content can be created by setting a proc or lambda value in a hash,
|
34
|
-
# and can reference any value stored in the +context+ object.
|
45
|
+
# Escaping is performed on the string returned, however untrusted user input should not be used.
|
35
46
|
#
|
36
47
|
# Example:
|
37
48
|
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
# end
|
54
|
-
#
|
55
|
-
# Direct updates to a context value:
|
56
|
-
#
|
57
|
-
# ActiveSupport::ExecutionContext[:foo] = Bar.new
|
49
|
+
# config.active_record.query_log_tags = [
|
50
|
+
# :namespaced_controller,
|
51
|
+
# :action,
|
52
|
+
# :job,
|
53
|
+
# {
|
54
|
+
# request_id: ->(context) { context[:controller]&.request&.request_id },
|
55
|
+
# job_id: ->(context) { context[:job]&.job_id },
|
56
|
+
# tenant_id: -> { Current.tenant&.id },
|
57
|
+
# static: "value",
|
58
|
+
# },
|
59
|
+
# ]
|
60
|
+
#
|
61
|
+
# By default the name of the application, the name and action of the controller, or the name of the job are logged
|
62
|
+
# using the {SQLCommenter}[https://open-telemetry.github.io/opentelemetry-sqlcommenter/] format. This can be changed
|
63
|
+
# via {config.active_record.query_log_tags_format}[https://guides.rubyonrails.org/configuring.html#config-active-record-query-log-tags-format]
|
58
64
|
#
|
59
65
|
# Tag comments can be prepended to the query:
|
60
66
|
#
|
@@ -63,59 +69,88 @@ module ActiveRecord
|
|
63
69
|
# For applications where the content will not change during the lifetime of
|
64
70
|
# the request or job execution, the tags can be cached for reuse in every query:
|
65
71
|
#
|
66
|
-
# ActiveRecord::QueryLogs.cache_query_log_tags = true
|
67
|
-
#
|
68
|
-
# This option can be set during application configuration or in a Rails initializer:
|
69
|
-
#
|
70
72
|
# config.active_record.cache_query_log_tags = true
|
71
73
|
module QueryLogs
|
72
74
|
mattr_accessor :taggings, instance_accessor: false, default: {}
|
73
75
|
mattr_accessor :tags, instance_accessor: false, default: [ :application ]
|
74
76
|
mattr_accessor :prepend_comment, instance_accessor: false, default: false
|
75
77
|
mattr_accessor :cache_query_log_tags, instance_accessor: false, default: false
|
78
|
+
mattr_accessor :tags_formatter, instance_accessor: false
|
76
79
|
thread_mattr_accessor :cached_comment, instance_accessor: false
|
77
80
|
|
78
81
|
class << self
|
79
|
-
def call(sql) # :nodoc:
|
80
|
-
|
81
|
-
|
82
|
+
def call(sql, connection) # :nodoc:
|
83
|
+
comment = self.comment(connection)
|
84
|
+
|
85
|
+
if comment.blank?
|
86
|
+
sql
|
87
|
+
elsif prepend_comment
|
88
|
+
"#{comment} #{sql}"
|
82
89
|
else
|
83
|
-
"#{sql} #{
|
84
|
-
end
|
90
|
+
"#{sql} #{comment}"
|
91
|
+
end
|
85
92
|
end
|
86
93
|
|
87
94
|
def clear_cache # :nodoc:
|
88
95
|
self.cached_comment = nil
|
89
96
|
end
|
90
97
|
|
98
|
+
# Updates the formatter to be what the passed in format is.
|
99
|
+
def update_formatter(format)
|
100
|
+
self.tags_formatter =
|
101
|
+
case format
|
102
|
+
when :legacy
|
103
|
+
LegacyFormatter.new
|
104
|
+
when :sqlcommenter
|
105
|
+
SQLCommenter.new
|
106
|
+
else
|
107
|
+
raise ArgumentError, "Formatter is unsupported: #{formatter}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
91
111
|
ActiveSupport::ExecutionContext.after_change { ActiveRecord::QueryLogs.clear_cache }
|
92
112
|
|
93
113
|
private
|
94
114
|
# Returns an SQL comment +String+ containing the query log tags.
|
95
115
|
# Sets and returns a cached comment if <tt>cache_query_log_tags</tt> is +true+.
|
96
|
-
def comment
|
116
|
+
def comment(connection)
|
97
117
|
if cache_query_log_tags
|
98
|
-
self.cached_comment ||= uncached_comment
|
118
|
+
self.cached_comment ||= uncached_comment(connection)
|
99
119
|
else
|
100
|
-
uncached_comment
|
120
|
+
uncached_comment(connection)
|
101
121
|
end
|
102
122
|
end
|
103
123
|
|
104
|
-
def
|
105
|
-
|
124
|
+
def formatter
|
125
|
+
self.tags_formatter || self.update_formatter(:legacy)
|
126
|
+
end
|
127
|
+
|
128
|
+
def uncached_comment(connection)
|
129
|
+
content = tag_content(connection)
|
130
|
+
|
106
131
|
if content.present?
|
107
132
|
"/*#{escape_sql_comment(content)}*/"
|
108
133
|
end
|
109
134
|
end
|
110
135
|
|
111
136
|
def escape_sql_comment(content)
|
112
|
-
|
137
|
+
# Sanitize a string to appear within a SQL comment
|
138
|
+
# For compatibility, this also surrounding "/*+", "/*", and "*/"
|
139
|
+
# characters, possibly with single surrounding space.
|
140
|
+
# Then follows that by replacing any internal "*/" or "/ *" with
|
141
|
+
# "* /" or "/ *"
|
142
|
+
comment = content.to_s.dup
|
143
|
+
comment.gsub!(%r{\A\s*/\*\+?\s?|\s?\*/\s*\Z}, "")
|
144
|
+
comment.gsub!("*/", "* /")
|
145
|
+
comment.gsub!("/*", "/ *")
|
146
|
+
comment
|
113
147
|
end
|
114
148
|
|
115
|
-
def tag_content
|
149
|
+
def tag_content(connection)
|
116
150
|
context = ActiveSupport::ExecutionContext.to_h
|
151
|
+
context[:connection] ||= connection
|
117
152
|
|
118
|
-
tags.flat_map { |i| [*i] }.filter_map do |tag|
|
153
|
+
pairs = tags.flat_map { |i| [*i] }.filter_map do |tag|
|
119
154
|
key, handler = tag
|
120
155
|
handler ||= taggings[key]
|
121
156
|
|
@@ -130,8 +165,9 @@ module ActiveRecord
|
|
130
165
|
else
|
131
166
|
handler
|
132
167
|
end
|
133
|
-
|
134
|
-
end
|
168
|
+
[key, val] unless val.nil?
|
169
|
+
end
|
170
|
+
self.formatter.format(pairs)
|
135
171
|
end
|
136
172
|
end
|
137
173
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module QueryLogs
|
5
|
+
class LegacyFormatter # :nodoc:
|
6
|
+
def initialize
|
7
|
+
@key_value_separator = ":"
|
8
|
+
end
|
9
|
+
|
10
|
+
# Formats the key value pairs into a string.
|
11
|
+
def format(pairs)
|
12
|
+
pairs.map! do |key, value|
|
13
|
+
"#{key}#{key_value_separator}#{format_value(value)}"
|
14
|
+
end.join(",")
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
attr_reader :key_value_separator
|
19
|
+
|
20
|
+
def format_value(value)
|
21
|
+
value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class SQLCommenter < LegacyFormatter # :nodoc:
|
26
|
+
def initialize
|
27
|
+
@key_value_separator = "="
|
28
|
+
end
|
29
|
+
|
30
|
+
def format(pairs)
|
31
|
+
pairs.sort_by!(&:first)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def format_value(value)
|
37
|
+
"'#{ERB::Util.url_encode(value)}'"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -12,12 +12,13 @@ module ActiveRecord
|
|
12
12
|
:create_or_find_by, :create_or_find_by!,
|
13
13
|
:destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
|
14
14
|
:find_each, :find_in_batches, :in_batches,
|
15
|
-
:select, :reselect, :order, :in_order_of, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
|
15
|
+
:select, :reselect, :order, :regroup, :in_order_of, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
|
16
16
|
:where, :rewhere, :invert_where, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly,
|
17
17
|
:and, :or, :annotate, :optimizer_hints, :extending,
|
18
18
|
:having, :create_with, :distinct, :references, :none, :unscope, :merge, :except, :only,
|
19
19
|
:count, :average, :minimum, :maximum, :sum, :calculate,
|
20
|
-
:pluck, :pick, :ids, :strict_loading, :excluding, :without
|
20
|
+
:pluck, :pick, :ids, :async_ids, :strict_loading, :excluding, :without, :with,
|
21
|
+
:async_count, :async_average, :async_minimum, :async_maximum, :async_sum, :async_pluck, :async_pick,
|
21
22
|
].freeze # :nodoc:
|
22
23
|
delegate(*QUERYING_METHODS, to: :all)
|
23
24
|
|
@@ -39,7 +40,7 @@ module ActiveRecord
|
|
39
40
|
# Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
|
40
41
|
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "author"=>"Quentin"}>, ...]
|
41
42
|
#
|
42
|
-
# You can use the same string replacement techniques as you can with
|
43
|
+
# You can use the same string replacement techniques as you can with ActiveRecord::QueryMethods#where :
|
43
44
|
#
|
44
45
|
# Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
|
45
46
|
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
|
@@ -50,6 +51,13 @@ module ActiveRecord
|
|
50
51
|
_load_from_sql(_query_by_sql(sql, binds, preparable: preparable), &block)
|
51
52
|
end
|
52
53
|
|
54
|
+
# Same as <tt>#find_by_sql</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
55
|
+
def async_find_by_sql(sql, binds = [], preparable: nil, &block)
|
56
|
+
_query_by_sql(sql, binds, preparable: preparable, async: true).then do |result|
|
57
|
+
_load_from_sql(result, &block)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
53
61
|
def _query_by_sql(sql, binds = [], preparable: nil, async: false) # :nodoc:
|
54
62
|
connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable, async: async)
|
55
63
|
end
|
@@ -93,5 +101,10 @@ module ActiveRecord
|
|
93
101
|
def count_by_sql(sql)
|
94
102
|
connection.select_value(sanitize_sql(sql), "#{name} Count").to_i
|
95
103
|
end
|
104
|
+
|
105
|
+
# Same as <tt>#count_by_sql</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
106
|
+
def async_count_by_sql(sql)
|
107
|
+
connection.select_value(sanitize_sql(sql), "#{name} Count", async: true).then(&:to_i)
|
108
|
+
end
|
96
109
|
end
|
97
110
|
end
|
@@ -34,7 +34,11 @@ module ActiveRecord
|
|
34
34
|
config.active_record.sqlite3_production_warning = true
|
35
35
|
config.active_record.query_log_tags_enabled = false
|
36
36
|
config.active_record.query_log_tags = [ :application ]
|
37
|
+
config.active_record.query_log_tags_format = :legacy
|
37
38
|
config.active_record.cache_query_log_tags = false
|
39
|
+
config.active_record.raise_on_assign_to_attr_readonly = false
|
40
|
+
config.active_record.belongs_to_required_validates_foreign_key = true
|
41
|
+
config.active_record.generate_secure_token_on = :create
|
38
42
|
|
39
43
|
config.active_record.queues = ActiveSupport::InheritableOptions.new
|
40
44
|
|
@@ -63,7 +67,7 @@ module ActiveRecord
|
|
63
67
|
unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
|
64
68
|
console = ActiveSupport::Logger.new(STDERR)
|
65
69
|
console.level = Rails.logger.level
|
66
|
-
Rails.logger.
|
70
|
+
Rails.logger.broadcast_to(console)
|
67
71
|
end
|
68
72
|
ActiveRecord.verbose_query_logs = false
|
69
73
|
end
|
@@ -72,12 +76,22 @@ module ActiveRecord
|
|
72
76
|
require "active_record/base"
|
73
77
|
end
|
74
78
|
|
79
|
+
initializer "active_record.deprecator", before: :load_environment_config do |app|
|
80
|
+
app.deprecators[:active_record] = ActiveRecord.deprecator
|
81
|
+
end
|
82
|
+
|
75
83
|
initializer "active_record.initialize_timezone" do
|
76
84
|
ActiveSupport.on_load(:active_record) do
|
77
85
|
self.time_zone_aware_attributes = true
|
78
86
|
end
|
79
87
|
end
|
80
88
|
|
89
|
+
initializer "active_record.postgresql_time_zone_aware_types" do
|
90
|
+
ActiveSupport.on_load(:active_record_postgresqladapter) do
|
91
|
+
ActiveRecord::Base.time_zone_aware_types << :timestamptz
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
81
95
|
initializer "active_record.logger" do
|
82
96
|
ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
|
83
97
|
end
|
@@ -94,23 +108,7 @@ module ActiveRecord
|
|
94
108
|
end
|
95
109
|
end
|
96
110
|
|
97
|
-
initializer "active_record.
|
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
|
-
initializer "Check for cache versioning support" do
|
111
|
+
initializer "active_record.cache_versioning_support" do
|
114
112
|
config.after_initialize do |app|
|
115
113
|
ActiveSupport.on_load(:active_record) do
|
116
114
|
if app.config.active_record.cache_versioning && Rails.cache
|
@@ -135,9 +133,15 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
135
133
|
end
|
136
134
|
end
|
137
135
|
|
136
|
+
initializer "active_record.use_schema_cache_dump" do
|
137
|
+
ActiveRecord::ConnectionAdapters::SchemaReflection.use_schema_cache_dump = config.active_record.use_schema_cache_dump
|
138
|
+
end
|
139
|
+
|
138
140
|
initializer "active_record.check_schema_cache_dump" do
|
139
141
|
check_schema_cache_dump_version = config.active_record.check_schema_cache_dump_version
|
140
142
|
|
143
|
+
ActiveRecord::ConnectionAdapters::SchemaReflection.check_schema_cache_dump_version = check_schema_cache_dump_version
|
144
|
+
|
141
145
|
if config.active_record.use_schema_cache_dump && !config.active_record.lazily_load_schema_cache
|
142
146
|
config.after_initialize do |app|
|
143
147
|
ActiveSupport.on_load(:active_record) do
|
@@ -145,10 +149,10 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
145
149
|
|
146
150
|
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
|
147
151
|
db_config.name,
|
148
|
-
schema_cache_path: db_config
|
152
|
+
schema_cache_path: db_config.schema_cache_path
|
149
153
|
)
|
150
154
|
|
151
|
-
cache = ActiveRecord::ConnectionAdapters::SchemaCache.
|
155
|
+
cache = ActiveRecord::ConnectionAdapters::SchemaCache._load_from(filename)
|
152
156
|
next if cache.nil?
|
153
157
|
|
154
158
|
if check_schema_cache_dump_version
|
@@ -160,34 +164,47 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
160
164
|
end
|
161
165
|
next if current_version.nil?
|
162
166
|
|
163
|
-
if cache.
|
164
|
-
warn "Ignoring #{filename} because it has expired. The current schema version is #{current_version}, but the one in the schema cache file is #{cache.
|
167
|
+
if cache.schema_version != current_version
|
168
|
+
warn "Ignoring #{filename} because it has expired. The current schema version is #{current_version}, but the one in the schema cache file is #{cache.schema_version}."
|
165
169
|
next
|
166
170
|
end
|
167
171
|
end
|
168
172
|
|
169
173
|
Rails.logger.info("Using schema cache file #{filename}")
|
170
|
-
connection_pool.set_schema_cache(cache)
|
174
|
+
connection_pool.schema_reflection.set_schema_cache(cache)
|
171
175
|
end
|
172
176
|
end
|
173
177
|
end
|
174
178
|
end
|
175
179
|
|
176
180
|
initializer "active_record.define_attribute_methods" do |app|
|
181
|
+
# For resiliency, it is critical that a Rails application should be
|
182
|
+
# able to boot without depending on the database (or any other service)
|
183
|
+
# being responsive.
|
184
|
+
#
|
185
|
+
# Otherwise a bad deploy adding a lot of load on the database may require to
|
186
|
+
# entirely shutdown the application so the database can recover before a fixed
|
187
|
+
# version can be deployed again.
|
188
|
+
#
|
189
|
+
# This is why this initializer tries hard not to query the database, and if it
|
190
|
+
# does, it makes sure to rescue any possible database error.
|
191
|
+
check_schema_cache_dump_version = config.active_record.check_schema_cache_dump_version
|
177
192
|
config.after_initialize do
|
178
193
|
ActiveSupport.on_load(:active_record) do
|
179
|
-
|
194
|
+
# In development and test we shouldn't eagerly define attribute methods because
|
195
|
+
# db:test:prepare will trigger later and might change the schema.
|
196
|
+
#
|
197
|
+
# Additionally if `check_schema_cache_dump_version` is enabled (which is the default),
|
198
|
+
# loading the schema cache dump trigger a database connection to compare the schema
|
199
|
+
# versions.
|
200
|
+
# This means the attribute methods will be lazily defined whent the model is accessed,
|
201
|
+
# likely as part of the first few requests or jobs. This isn't good for performance
|
202
|
+
# but we unfortunately have to arbitrate between resiliency and performance, and chose
|
203
|
+
# resiliency.
|
204
|
+
if !check_schema_cache_dump_version && app.config.eager_load && !Rails.env.local?
|
180
205
|
begin
|
181
206
|
descendants.each do |model|
|
182
|
-
|
183
|
-
schema_cache = model.connection_pool.schema_cache
|
184
|
-
|
185
|
-
# If there's no connection yet, we avoid connecting.
|
186
|
-
schema_cache ||= model.connected? && model.connection.schema_cache
|
187
|
-
|
188
|
-
# If the schema cache doesn't have the columns
|
189
|
-
# hash for the model cached, `define_attribute_methods` would trigger a query.
|
190
|
-
if schema_cache && schema_cache.columns_hash?(model.table_name)
|
207
|
+
if model.connection_pool.schema_reflection.cached?(model.table_name)
|
191
208
|
model.define_attribute_methods
|
192
209
|
end
|
193
210
|
end
|
@@ -220,6 +237,16 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
220
237
|
end
|
221
238
|
end
|
222
239
|
|
240
|
+
initializer "active_record.sqlite3_adapter_strict_strings_by_default" do
|
241
|
+
config.after_initialize do
|
242
|
+
if config.active_record.sqlite3_adapter_strict_strings_by_default
|
243
|
+
ActiveSupport.on_load(:active_record_sqlite3adapter) do
|
244
|
+
self.strict_strings_by_default = true
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
223
250
|
initializer "active_record.set_configs" do |app|
|
224
251
|
configs = app.config.active_record
|
225
252
|
|
@@ -244,8 +271,10 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
244
271
|
:shard_resolver,
|
245
272
|
:query_log_tags_enabled,
|
246
273
|
:query_log_tags,
|
274
|
+
:query_log_tags_format,
|
247
275
|
:cache_query_log_tags,
|
248
276
|
:sqlite3_production_warning,
|
277
|
+
:sqlite3_adapter_strict_strings_by_default,
|
249
278
|
:check_schema_cache_dump_version,
|
250
279
|
:use_schema_cache_dump
|
251
280
|
)
|
@@ -270,21 +299,23 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
270
299
|
# and then establishes the connection.
|
271
300
|
initializer "active_record.initialize_database" do
|
272
301
|
ActiveSupport.on_load(:active_record) do
|
273
|
-
if ActiveRecord.legacy_connection_handling
|
274
|
-
self.connection_handlers = { ActiveRecord.writing_role => ActiveRecord::Base.default_connection_handler }
|
275
|
-
end
|
276
302
|
self.configurations = Rails.application.config.database_configuration
|
277
303
|
|
278
304
|
establish_connection
|
279
305
|
end
|
280
306
|
end
|
281
307
|
|
282
|
-
# Expose database runtime
|
308
|
+
# Expose database runtime for logging.
|
283
309
|
initializer "active_record.log_runtime" do
|
284
310
|
require "active_record/railties/controller_runtime"
|
285
311
|
ActiveSupport.on_load(:action_controller) do
|
286
312
|
include ActiveRecord::Railties::ControllerRuntime
|
287
313
|
end
|
314
|
+
|
315
|
+
require "active_record/railties/job_runtime"
|
316
|
+
ActiveSupport.on_load(:active_job) do
|
317
|
+
include ActiveRecord::Railties::JobRuntime
|
318
|
+
end
|
288
319
|
end
|
289
320
|
|
290
321
|
initializer "active_record.set_reloader_hooks" do
|
@@ -292,7 +323,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
292
323
|
ActiveSupport::Reloader.before_class_unload do
|
293
324
|
if ActiveRecord::Base.connected?
|
294
325
|
ActiveRecord::Base.clear_cache!
|
295
|
-
ActiveRecord::Base.clear_reloadable_connections!
|
326
|
+
ActiveRecord::Base.connection_handler.clear_reloadable_connections!(:all)
|
296
327
|
end
|
297
328
|
end
|
298
329
|
end
|
@@ -319,8 +350,8 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
319
350
|
# this connection is trivial: the rest of the pool would need to be
|
320
351
|
# populated anyway.
|
321
352
|
|
322
|
-
clear_active_connections!
|
323
|
-
flush_idle_connections!
|
353
|
+
connection_handler.clear_active_connections!(:all)
|
354
|
+
connection_handler.flush_idle_connections!(:all)
|
324
355
|
end
|
325
356
|
end
|
326
357
|
end
|
@@ -337,18 +368,32 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
337
368
|
end
|
338
369
|
end
|
339
370
|
|
371
|
+
initializer "active_record.generated_token_verifier" do
|
372
|
+
config.after_initialize do |app|
|
373
|
+
ActiveSupport.on_load(:active_record) do
|
374
|
+
self.generated_token_verifier ||= app.message_verifier("active_record/token_for")
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
340
379
|
initializer "active_record_encryption.configuration" do |app|
|
341
|
-
ActiveRecord::Encryption.
|
342
|
-
primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
|
343
|
-
deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
|
344
|
-
key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
|
345
|
-
**config.active_record.encryption
|
380
|
+
auto_filtered_parameters = ActiveRecord::Encryption::AutoFilteredParameters.new(app)
|
346
381
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
382
|
+
config.after_initialize do |app|
|
383
|
+
ActiveRecord::Encryption.configure \
|
384
|
+
primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
|
385
|
+
deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
|
386
|
+
key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
|
387
|
+
**config.active_record.encryption
|
388
|
+
|
389
|
+
auto_filtered_parameters.enable if ActiveRecord::Encryption.config.add_to_filter_parameters
|
390
|
+
|
391
|
+
ActiveSupport.on_load(:active_record) do
|
392
|
+
# Support extended queries for deterministic attributes and validations
|
393
|
+
if ActiveRecord::Encryption.config.extend_queries
|
394
|
+
ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
|
395
|
+
ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
|
396
|
+
end
|
352
397
|
end
|
353
398
|
end
|
354
399
|
|
@@ -358,13 +403,6 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
358
403
|
ActiveRecord::Fixture.prepend ActiveRecord::Encryption::EncryptedFixtures
|
359
404
|
end
|
360
405
|
end
|
361
|
-
|
362
|
-
# Filtered params
|
363
|
-
ActiveSupport.on_load(:action_controller) do
|
364
|
-
if ActiveRecord::Encryption.config.add_to_filter_parameters
|
365
|
-
ActiveRecord::Encryption.install_auto_filtered_parameters(app)
|
366
|
-
end
|
367
|
-
end
|
368
406
|
end
|
369
407
|
|
370
408
|
initializer "active_record.query_log_tags_config" do |app|
|
@@ -373,21 +411,49 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
373
411
|
ActiveRecord.query_transformers << ActiveRecord::QueryLogs
|
374
412
|
ActiveRecord::QueryLogs.taggings.merge!(
|
375
413
|
application: Rails.application.class.name.split("::").first,
|
376
|
-
pid: -> { Process.pid },
|
377
|
-
socket: -> {
|
378
|
-
db_host: -> {
|
379
|
-
database: -> {
|
414
|
+
pid: -> { Process.pid.to_s },
|
415
|
+
socket: ->(context) { context[:connection].pool.db_config.socket },
|
416
|
+
db_host: ->(context) { context[:connection].pool.db_config.host },
|
417
|
+
database: ->(context) { context[:connection].pool.db_config.database }
|
380
418
|
)
|
419
|
+
ActiveRecord.disable_prepared_statements = true
|
381
420
|
|
382
421
|
if app.config.active_record.query_log_tags.present?
|
383
422
|
ActiveRecord::QueryLogs.tags = app.config.active_record.query_log_tags
|
384
423
|
end
|
385
424
|
|
425
|
+
if app.config.active_record.query_log_tags_format
|
426
|
+
ActiveRecord::QueryLogs.update_formatter(app.config.active_record.query_log_tags_format)
|
427
|
+
end
|
428
|
+
|
386
429
|
if app.config.active_record.cache_query_log_tags
|
387
430
|
ActiveRecord::QueryLogs.cache_query_log_tags = true
|
388
431
|
end
|
389
432
|
end
|
390
433
|
end
|
391
434
|
end
|
435
|
+
|
436
|
+
initializer "active_record.unregister_current_scopes_on_unload" do |app|
|
437
|
+
config.after_initialize do
|
438
|
+
if app.config.reloading_enabled?
|
439
|
+
Rails.autoloaders.main.on_unload do |_cpath, value, _abspath|
|
440
|
+
# Conditions are written this way to be robust against custom
|
441
|
+
# implementations of value#is_a? or value#<.
|
442
|
+
if Class === value && ActiveRecord::Base > value
|
443
|
+
value.current_scope = nil
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
initializer "active_record.message_pack" do
|
451
|
+
ActiveSupport.on_load(:message_pack) do
|
452
|
+
ActiveSupport.on_load(:active_record) do
|
453
|
+
require "active_record/message_pack"
|
454
|
+
ActiveRecord::MessagePack::Extensions.install(ActiveSupport::MessagePack::CacheSerializer)
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
392
458
|
end
|
393
459
|
end
|