activerecord 6.1.7.4 → 7.0.6
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 +1449 -1014
- data/README.rdoc +3 -3
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +0 -10
- data/lib/active_record/associations/association.rb +33 -17
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +15 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +8 -2
- data/lib/active_record/associations/builder/belongs_to.rb +19 -6
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +19 -21
- data/lib/active_record/associations/collection_proxy.rb +10 -5
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +8 -5
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +14 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +23 -15
- data/lib/active_record/associations/preloader/association.rb +186 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +50 -14
- data/lib/active_record/associations/preloader.rb +39 -113
- data/lib/active_record/associations/singular_association.rb +15 -7
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +138 -100
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +49 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +8 -6
- data/lib/active_record/attribute_methods/serialization.rb +57 -19
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +19 -22
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +17 -28
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +14 -16
- data/lib/active_record/coders/yaml_column.rb +4 -8
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +52 -23
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +82 -25
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
- data/lib/active_record/connection_adapters/abstract_adapter.rb +153 -74
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +112 -84
- data/lib/active_record/connection_adapters/column.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -24
- data/lib/active_record/connection_adapters/mysql/quoting.rb +45 -21
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +4 -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/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +19 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -17
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +71 -71
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +40 -21
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -106
- data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +28 -16
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +17 -15
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +97 -32
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +49 -55
- data/lib/active_record/core.rb +123 -148
- data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -9
- data/lib/active_record/database_configurations/hash_config.rb +63 -5
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +15 -32
- data/lib/active_record/delegated_type.rb +53 -12
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +44 -0
- data/lib/active_record/encryption/configurable.rb +67 -0
- data/lib/active_record/encryption/context.rb +35 -0
- data/lib/active_record/encryption/contexts.rb +72 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +206 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +42 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +90 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +99 -0
- data/lib/active_record/encryption.rb +55 -0
- data/lib/active_record/enum.rb +50 -43
- data/lib/active_record/errors.rb +67 -4
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +41 -6
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +20 -23
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +5 -5
- data/lib/active_record/inheritance.rb +55 -17
- data/lib/active_record/insert_all.rb +80 -14
- data/lib/active_record/integration.rb +4 -3
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +36 -21
- data/lib/active_record/locking/pessimistic.rb +10 -4
- data/lib/active_record/log_subscriber.rb +23 -7
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +18 -6
- data/lib/active_record/middleware/shard_selector.rb +60 -0
- data/lib/active_record/migration/command_recorder.rb +8 -9
- data/lib/active_record/migration/compatibility.rb +91 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +115 -84
- data/lib/active_record/model_schema.rb +58 -59
- data/lib/active_record/nested_attributes.rb +13 -12
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +228 -60
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +149 -0
- data/lib/active_record/querying.rb +16 -6
- data/lib/active_record/railtie.rb +136 -22
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +78 -136
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +80 -49
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +6 -6
- data/lib/active_record/relation/calculations.rb +92 -60
- data/lib/active_record/relation/delegation.rb +7 -7
- data/lib/active_record/relation/finder_methods.rb +31 -35
- data/lib/active_record/relation/merger.rb +20 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +20 -1
- data/lib/active_record/relation/predicate_builder.rb +2 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +285 -68
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +189 -88
- data/lib/active_record/result.rb +23 -11
- data/lib/active_record/runtime_registry.rb +9 -13
- data/lib/active_record/sanitization.rb +17 -12
- data/lib/active_record/schema.rb +38 -23
- data/lib/active_record/schema_dumper.rb +29 -19
- data/lib/active_record/schema_migration.rb +4 -4
- data/lib/active_record/scoping/default.rb +60 -13
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +64 -34
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +3 -3
- data/lib/active_record/store.rb +2 -2
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/table_metadata.rb +5 -1
- data/lib/active_record/tasks/database_tasks.rb +127 -60
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -13
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +9 -6
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +3 -3
- data/lib/active_record/type/adapter_specific_registry.rb +32 -7
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +2 -2
- data/lib/active_record/type/serialized.rb +5 -5
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/associated.rb +4 -4
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +4 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +225 -27
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/predications.rb +11 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +0 -1
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +8 -2
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +58 -2
- data/lib/arel.rb +2 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +58 -14
@@ -20,25 +20,19 @@ module ActiveRecord
|
|
20
20
|
def nil?
|
21
21
|
unless value_before_type_cast.is_a?(StatementCache::Substitute)
|
22
22
|
value_before_type_cast.nil? ||
|
23
|
-
type.respond_to?(:subtype
|
23
|
+
type.respond_to?(:subtype) && serializable? && value_for_database.nil?
|
24
24
|
end
|
25
|
-
rescue ::RangeError
|
26
25
|
end
|
27
26
|
|
28
27
|
def infinite?
|
29
|
-
infinity?(value_before_type_cast) || infinity?(value_for_database)
|
30
|
-
rescue ::RangeError
|
28
|
+
infinity?(value_before_type_cast) || serializable? && infinity?(value_for_database)
|
31
29
|
end
|
32
30
|
|
33
31
|
def unboundable?
|
34
|
-
|
35
|
-
@_unboundable
|
36
|
-
else
|
37
|
-
value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
|
38
|
-
@_unboundable = nil
|
32
|
+
unless defined?(@_unboundable)
|
33
|
+
serializable? { |value| @_unboundable = value <=> 0 } && @_unboundable = nil
|
39
34
|
end
|
40
|
-
|
41
|
-
@_unboundable = type.cast(value_before_type_cast) <=> 0
|
35
|
+
@_unboundable
|
42
36
|
end
|
43
37
|
|
44
38
|
private
|
@@ -8,14 +8,12 @@ require "active_support/core_ext/array/wrap"
|
|
8
8
|
|
9
9
|
module ActiveRecord
|
10
10
|
module QueryMethods
|
11
|
-
extend ActiveSupport::Concern
|
12
|
-
|
13
11
|
include ActiveModel::ForbiddenAttributesProtection
|
14
12
|
|
15
|
-
# WhereChain objects act as placeholder for queries in which
|
16
|
-
# In this case,
|
13
|
+
# WhereChain objects act as placeholder for queries in which +where+ does not have any parameter.
|
14
|
+
# In this case, +where+ can be chained to return a new relation.
|
17
15
|
class WhereChain
|
18
|
-
def initialize(scope)
|
16
|
+
def initialize(scope) # :nodoc:
|
19
17
|
@scope = scope
|
20
18
|
end
|
21
19
|
|
@@ -42,6 +40,13 @@ module ActiveRecord
|
|
42
40
|
#
|
43
41
|
# User.where.not(name: "Jon", role: "admin")
|
44
42
|
# # SELECT * FROM users WHERE NOT (name == 'Jon' AND role == 'admin')
|
43
|
+
#
|
44
|
+
# If there is a non-nil condition on a nullable column in the hash condition, the records that have
|
45
|
+
# nil values on the nullable column won't be returned.
|
46
|
+
# User.create!(nullable_country: nil)
|
47
|
+
# User.where.not(nullable_country: "UK")
|
48
|
+
# # SELECT * FROM users WHERE NOT (nullable_country = 'UK')
|
49
|
+
# # => []
|
45
50
|
def not(opts, *rest)
|
46
51
|
where_clause = @scope.send(:build_where_clause, opts, rest)
|
47
52
|
|
@@ -50,6 +55,38 @@ module ActiveRecord
|
|
50
55
|
@scope
|
51
56
|
end
|
52
57
|
|
58
|
+
# Returns a new relation with joins and where clause to identify
|
59
|
+
# associated relations.
|
60
|
+
#
|
61
|
+
# For example, posts that are associated to a related author:
|
62
|
+
#
|
63
|
+
# Post.where.associated(:author)
|
64
|
+
# # SELECT "posts".* FROM "posts"
|
65
|
+
# # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
|
66
|
+
# # WHERE "authors"."id" IS NOT NULL
|
67
|
+
#
|
68
|
+
# Additionally, multiple relations can be combined. This will return posts
|
69
|
+
# associated to both an author and any comments:
|
70
|
+
#
|
71
|
+
# Post.where.associated(:author, :comments)
|
72
|
+
# # SELECT "posts".* FROM "posts"
|
73
|
+
# # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
|
74
|
+
# # INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
75
|
+
# # WHERE "authors"."id" IS NOT NULL AND "comments"."id" IS NOT NULL
|
76
|
+
def associated(*associations)
|
77
|
+
associations.each do |association|
|
78
|
+
reflection = scope_association_reflection(association)
|
79
|
+
@scope.joins!(association)
|
80
|
+
if @scope.table_name == reflection.table_name
|
81
|
+
self.not(association => { reflection.association_primary_key => nil })
|
82
|
+
else
|
83
|
+
self.not(reflection.table_name => { reflection.association_primary_key => nil })
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@scope
|
88
|
+
end
|
89
|
+
|
53
90
|
# Returns a new relation with left outer joins and where clause to identify
|
54
91
|
# missing relations.
|
55
92
|
#
|
@@ -68,16 +105,28 @@ module ActiveRecord
|
|
68
105
|
# # LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
|
69
106
|
# # LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
70
107
|
# # WHERE "authors"."id" IS NULL AND "comments"."id" IS NULL
|
71
|
-
def missing(*
|
72
|
-
|
73
|
-
reflection =
|
74
|
-
|
75
|
-
@scope.
|
76
|
-
|
108
|
+
def missing(*associations)
|
109
|
+
associations.each do |association|
|
110
|
+
reflection = scope_association_reflection(association)
|
111
|
+
@scope.left_outer_joins!(association)
|
112
|
+
if @scope.table_name == reflection.table_name
|
113
|
+
@scope.where!(association => { reflection.association_primary_key => nil })
|
114
|
+
else
|
115
|
+
@scope.where!(reflection.table_name => { reflection.association_primary_key => nil })
|
116
|
+
end
|
77
117
|
end
|
78
118
|
|
79
119
|
@scope
|
80
120
|
end
|
121
|
+
|
122
|
+
private
|
123
|
+
def scope_association_reflection(association)
|
124
|
+
reflection = @scope.klass._reflect_on_association(association)
|
125
|
+
unless reflection
|
126
|
+
raise ArgumentError.new("An association named `:#{association}` does not exist on the model `#{@scope.name}`.")
|
127
|
+
end
|
128
|
+
reflection
|
129
|
+
end
|
81
130
|
end
|
82
131
|
|
83
132
|
FROZEN_EMPTY_ARRAY = [].freeze
|
@@ -128,7 +177,7 @@ module ActiveRecord
|
|
128
177
|
#
|
129
178
|
# users = User.includes(:address, friends: [:address, :followers])
|
130
179
|
#
|
131
|
-
# ===
|
180
|
+
# === Conditions
|
132
181
|
#
|
133
182
|
# If you want to add string conditions to your included models, you'll have
|
134
183
|
# to explicitly reference them. For example:
|
@@ -148,7 +197,7 @@ module ActiveRecord
|
|
148
197
|
#
|
149
198
|
# User.includes(:posts).where(posts: { name: 'example' })
|
150
199
|
def includes(*args)
|
151
|
-
check_if_method_has_arguments!(
|
200
|
+
check_if_method_has_arguments!(__callee__, args)
|
152
201
|
spawn.includes!(*args)
|
153
202
|
end
|
154
203
|
|
@@ -164,7 +213,7 @@ module ActiveRecord
|
|
164
213
|
# # FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" =
|
165
214
|
# # "users"."id"
|
166
215
|
def eager_load(*args)
|
167
|
-
check_if_method_has_arguments!(
|
216
|
+
check_if_method_has_arguments!(__callee__, args)
|
168
217
|
spawn.eager_load!(*args)
|
169
218
|
end
|
170
219
|
|
@@ -178,7 +227,7 @@ module ActiveRecord
|
|
178
227
|
# User.preload(:posts)
|
179
228
|
# # SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3)
|
180
229
|
def preload(*args)
|
181
|
-
check_if_method_has_arguments!(
|
230
|
+
check_if_method_has_arguments!(__callee__, args)
|
182
231
|
spawn.preload!(*args)
|
183
232
|
end
|
184
233
|
|
@@ -211,7 +260,7 @@ module ActiveRecord
|
|
211
260
|
# User.includes(:posts).where("posts.name = 'foo'").references(:posts)
|
212
261
|
# # Query now knows the string references posts, so adds a JOIN
|
213
262
|
def references(*table_names)
|
214
|
-
check_if_method_has_arguments!(
|
263
|
+
check_if_method_has_arguments!(__callee__, table_names)
|
215
264
|
spawn.references!(*table_names)
|
216
265
|
end
|
217
266
|
|
@@ -248,7 +297,7 @@ module ActiveRecord
|
|
248
297
|
# You can also use one or more strings, which will be used unchanged as SELECT fields.
|
249
298
|
#
|
250
299
|
# Model.select('field AS field_one', 'other_field AS field_two')
|
251
|
-
# # => [#<Model id: nil,
|
300
|
+
# # => [#<Model id: nil, field_one: "value", field_two: "value">]
|
252
301
|
#
|
253
302
|
# If an alias was specified, it will be accessible from the resulting objects:
|
254
303
|
#
|
@@ -269,7 +318,7 @@ module ActiveRecord
|
|
269
318
|
return super()
|
270
319
|
end
|
271
320
|
|
272
|
-
check_if_method_has_arguments!(
|
321
|
+
check_if_method_has_arguments!(__callee__, fields, "Call `select' with at least one field.")
|
273
322
|
spawn._select!(*fields)
|
274
323
|
end
|
275
324
|
|
@@ -289,7 +338,7 @@ module ActiveRecord
|
|
289
338
|
# This is short-hand for <tt>unscope(:select).select(fields)</tt>.
|
290
339
|
# Note that we're unscoping the entire select statement.
|
291
340
|
def reselect(*args)
|
292
|
-
check_if_method_has_arguments!(
|
341
|
+
check_if_method_has_arguments!(__callee__, args)
|
293
342
|
spawn.reselect!(*args)
|
294
343
|
end
|
295
344
|
|
@@ -320,7 +369,7 @@ module ActiveRecord
|
|
320
369
|
# User.select([:id, :first_name]).group(:id, :first_name).first(3)
|
321
370
|
# # => [#<User id: 1, first_name: "Bill">, #<User id: 2, first_name: "Earl">, #<User id: 3, first_name: "Beto">]
|
322
371
|
def group(*args)
|
323
|
-
check_if_method_has_arguments!(
|
372
|
+
check_if_method_has_arguments!(__callee__, args)
|
324
373
|
spawn.group!(*args)
|
325
374
|
end
|
326
375
|
|
@@ -329,17 +378,37 @@ module ActiveRecord
|
|
329
378
|
self
|
330
379
|
end
|
331
380
|
|
332
|
-
#
|
381
|
+
# Applies an <code>ORDER BY</code> clause to a query.
|
382
|
+
#
|
383
|
+
# #order accepts arguments in one of several formats.
|
384
|
+
#
|
385
|
+
# === symbols
|
386
|
+
#
|
387
|
+
# The symbol represents the name of the column you want to order the results by.
|
333
388
|
#
|
334
389
|
# User.order(:name)
|
335
390
|
# # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC
|
336
391
|
#
|
392
|
+
# By default, the order is ascending. If you want descending order, you can
|
393
|
+
# map the column name symbol to +:desc+.
|
394
|
+
#
|
337
395
|
# User.order(email: :desc)
|
338
396
|
# # SELECT "users".* FROM "users" ORDER BY "users"."email" DESC
|
339
397
|
#
|
398
|
+
# Multiple columns can be passed this way, and they will be applied in the order specified.
|
399
|
+
#
|
340
400
|
# User.order(:name, email: :desc)
|
341
401
|
# # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC
|
342
402
|
#
|
403
|
+
# === strings
|
404
|
+
#
|
405
|
+
# Strings are passed directly to the database, allowing you to specify
|
406
|
+
# simple SQL expressions.
|
407
|
+
#
|
408
|
+
# This could be a source of SQL injection, so only strings composed of plain
|
409
|
+
# column names and simple <code>function(column_name)</code> expressions
|
410
|
+
# with optional +ASC+/+DESC+ modifiers are allowed.
|
411
|
+
#
|
343
412
|
# User.order('name')
|
344
413
|
# # SELECT "users".* FROM "users" ORDER BY name
|
345
414
|
#
|
@@ -348,8 +417,21 @@ module ActiveRecord
|
|
348
417
|
#
|
349
418
|
# User.order('name DESC, email')
|
350
419
|
# # SELECT "users".* FROM "users" ORDER BY name DESC, email
|
420
|
+
#
|
421
|
+
# === Arel
|
422
|
+
#
|
423
|
+
# If you need to pass in complicated expressions that you have verified
|
424
|
+
# are safe for the database, you can use Arel.
|
425
|
+
#
|
426
|
+
# User.order(Arel.sql('end_date - start_date'))
|
427
|
+
# # SELECT "users".* FROM "users" ORDER BY end_date - start_date
|
428
|
+
#
|
429
|
+
# Custom query syntax, like JSON columns for Postgres, is supported in this way.
|
430
|
+
#
|
431
|
+
# User.order(Arel.sql("payload->>'kind'"))
|
432
|
+
# # SELECT "users".* FROM "users" ORDER BY payload->>'kind'
|
351
433
|
def order(*args)
|
352
|
-
check_if_method_has_arguments!(
|
434
|
+
check_if_method_has_arguments!(__callee__, args) do
|
353
435
|
sanitize_order_arguments(args)
|
354
436
|
end
|
355
437
|
spawn.order!(*args)
|
@@ -362,6 +444,29 @@ module ActiveRecord
|
|
362
444
|
self
|
363
445
|
end
|
364
446
|
|
447
|
+
# Allows to specify an order by a specific set of values. Depending on your
|
448
|
+
# adapter this will either use a CASE statement or a built-in function.
|
449
|
+
#
|
450
|
+
# User.in_order_of(:id, [1, 5, 3])
|
451
|
+
# # SELECT "users".* FROM "users"
|
452
|
+
# # ORDER BY FIELD("users"."id", 1, 5, 3)
|
453
|
+
# # WHERE "users"."id" IN (1, 5, 3)
|
454
|
+
#
|
455
|
+
def in_order_of(column, values)
|
456
|
+
klass.disallow_raw_sql!([column], permit: connection.column_name_with_order_matcher)
|
457
|
+
return spawn.none! if values.empty?
|
458
|
+
|
459
|
+
references = column_references([column])
|
460
|
+
self.references_values |= references unless references.empty?
|
461
|
+
|
462
|
+
values = values.map { |value| type_caster.type_cast_for_database(column, value) }
|
463
|
+
arel_column = column.is_a?(Symbol) ? order_column(column.to_s) : column
|
464
|
+
|
465
|
+
spawn
|
466
|
+
.order!(connection.field_ordered_value(arel_column, values))
|
467
|
+
.where!(arel_column.in(values))
|
468
|
+
end
|
469
|
+
|
365
470
|
# Replaces any existing order defined on the relation with the specified order.
|
366
471
|
#
|
367
472
|
# User.order('email DESC').reorder('id ASC') # generated SQL has 'ORDER BY id ASC'
|
@@ -372,15 +477,15 @@ module ActiveRecord
|
|
372
477
|
#
|
373
478
|
# generates a query with 'ORDER BY id ASC, name ASC'.
|
374
479
|
def reorder(*args)
|
375
|
-
check_if_method_has_arguments!(
|
376
|
-
sanitize_order_arguments(args)
|
480
|
+
check_if_method_has_arguments!(__callee__, args) do
|
481
|
+
sanitize_order_arguments(args)
|
377
482
|
end
|
378
483
|
spawn.reorder!(*args)
|
379
484
|
end
|
380
485
|
|
381
486
|
# Same as #reorder but operates on relation in-place instead of copying.
|
382
487
|
def reorder!(*args) # :nodoc:
|
383
|
-
preprocess_order_args(args)
|
488
|
+
preprocess_order_args(args)
|
384
489
|
args.uniq!
|
385
490
|
self.reordering_value = true
|
386
491
|
self.order_values = args
|
@@ -425,7 +530,7 @@ module ActiveRecord
|
|
425
530
|
# has_many :comments, -> { unscope(where: :trashed) }
|
426
531
|
#
|
427
532
|
def unscope(*args)
|
428
|
-
check_if_method_has_arguments!(
|
533
|
+
check_if_method_has_arguments!(__callee__, args)
|
429
534
|
spawn.unscope!(*args)
|
430
535
|
end
|
431
536
|
|
@@ -458,7 +563,7 @@ module ActiveRecord
|
|
458
563
|
self
|
459
564
|
end
|
460
565
|
|
461
|
-
# Performs
|
566
|
+
# Performs JOINs on +args+. The given symbol(s) should match the name of
|
462
567
|
# the association(s).
|
463
568
|
#
|
464
569
|
# User.joins(:posts)
|
@@ -487,7 +592,7 @@ module ActiveRecord
|
|
487
592
|
# User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id")
|
488
593
|
# # SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
|
489
594
|
def joins(*args)
|
490
|
-
check_if_method_has_arguments!(
|
595
|
+
check_if_method_has_arguments!(__callee__, args)
|
491
596
|
spawn.joins!(*args)
|
492
597
|
end
|
493
598
|
|
@@ -496,7 +601,7 @@ module ActiveRecord
|
|
496
601
|
self
|
497
602
|
end
|
498
603
|
|
499
|
-
# Performs
|
604
|
+
# Performs LEFT OUTER JOINs on +args+:
|
500
605
|
#
|
501
606
|
# User.left_outer_joins(:posts)
|
502
607
|
# => SELECT "users".* FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
|
@@ -578,13 +683,13 @@ module ActiveRecord
|
|
578
683
|
#
|
579
684
|
# Fields can be symbols or strings. Values can be single values, arrays, or ranges.
|
580
685
|
#
|
581
|
-
# User.where(
|
686
|
+
# User.where(name: "Joe", email: "joe@example.com")
|
582
687
|
# # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'
|
583
688
|
#
|
584
|
-
# User.where(
|
689
|
+
# User.where(name: ["Alice", "Bob"])
|
585
690
|
# # SELECT * FROM users WHERE name IN ('Alice', 'Bob')
|
586
691
|
#
|
587
|
-
# User.where(
|
692
|
+
# User.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
|
588
693
|
# # SELECT * FROM users WHERE (created_at BETWEEN '2012-06-09 07:00:00.000000' AND '2012-06-10 07:00:00.000000')
|
589
694
|
#
|
590
695
|
# In the case of a belongs_to relationship, an association key can be used
|
@@ -614,18 +719,32 @@ module ActiveRecord
|
|
614
719
|
#
|
615
720
|
# For hash conditions, you can either use the table name in the key, or use a sub-hash.
|
616
721
|
#
|
617
|
-
# User.joins(:posts).where(
|
618
|
-
# User.joins(:posts).where(
|
722
|
+
# User.joins(:posts).where("posts.published" => true)
|
723
|
+
# User.joins(:posts).where(posts: { published: true })
|
619
724
|
#
|
620
725
|
# === no argument
|
621
726
|
#
|
622
727
|
# If no argument is passed, #where returns a new instance of WhereChain, that
|
623
|
-
# can be chained with #not
|
728
|
+
# can be chained with WhereChain#not, WhereChain#missing, or WhereChain#associated.
|
729
|
+
#
|
730
|
+
# Chaining with WhereChain#not:
|
624
731
|
#
|
625
732
|
# User.where.not(name: "Jon")
|
626
733
|
# # SELECT * FROM users WHERE name != 'Jon'
|
627
734
|
#
|
628
|
-
#
|
735
|
+
# Chaining with WhereChain#associated:
|
736
|
+
#
|
737
|
+
# Post.where.associated(:author)
|
738
|
+
# # SELECT "posts".* FROM "posts"
|
739
|
+
# # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
|
740
|
+
# # WHERE "authors"."id" IS NOT NULL
|
741
|
+
#
|
742
|
+
# Chaining with WhereChain#missing:
|
743
|
+
#
|
744
|
+
# Post.where.missing(:author)
|
745
|
+
# # SELECT "posts".* FROM "posts"
|
746
|
+
# # LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
|
747
|
+
# # WHERE "authors"."id" IS NULL
|
629
748
|
#
|
630
749
|
# === blank condition
|
631
750
|
#
|
@@ -668,6 +787,59 @@ module ActiveRecord
|
|
668
787
|
scope
|
669
788
|
end
|
670
789
|
|
790
|
+
# Allows you to invert an entire where clause instead of manually applying conditions.
|
791
|
+
#
|
792
|
+
# class User
|
793
|
+
# scope :active, -> { where(accepted: true, locked: false) }
|
794
|
+
# end
|
795
|
+
#
|
796
|
+
# User.where(accepted: true)
|
797
|
+
# # WHERE `accepted` = 1
|
798
|
+
#
|
799
|
+
# User.where(accepted: true).invert_where
|
800
|
+
# # WHERE `accepted` != 1
|
801
|
+
#
|
802
|
+
# User.active
|
803
|
+
# # WHERE `accepted` = 1 AND `locked` = 0
|
804
|
+
#
|
805
|
+
# User.active.invert_where
|
806
|
+
# # WHERE NOT (`accepted` = 1 AND `locked` = 0)
|
807
|
+
#
|
808
|
+
# Be careful because this inverts all conditions before +invert_where+ call.
|
809
|
+
#
|
810
|
+
# class User
|
811
|
+
# scope :active, -> { where(accepted: true, locked: false) }
|
812
|
+
# scope :inactive, -> { active.invert_where } # Do not attempt it
|
813
|
+
# end
|
814
|
+
#
|
815
|
+
# # It also inverts `where(role: 'admin')` unexpectedly.
|
816
|
+
# User.where(role: 'admin').inactive
|
817
|
+
# # WHERE NOT (`role` = 'admin' AND `accepted` = 1 AND `locked` = 0)
|
818
|
+
#
|
819
|
+
def invert_where
|
820
|
+
spawn.invert_where!
|
821
|
+
end
|
822
|
+
|
823
|
+
def invert_where! # :nodoc:
|
824
|
+
self.where_clause = where_clause.invert
|
825
|
+
self
|
826
|
+
end
|
827
|
+
|
828
|
+
# Checks whether the given relation is structurally compatible with this relation, to determine
|
829
|
+
# if it's possible to use the #and and #or methods without raising an error. Structurally
|
830
|
+
# compatible is defined as: they must be scoping the same model, and they must differ only by
|
831
|
+
# #where (if no #group has been defined) or #having (if a #group is present).
|
832
|
+
#
|
833
|
+
# Post.where("id = 1").structurally_compatible?(Post.where("author_id = 3"))
|
834
|
+
# # => true
|
835
|
+
#
|
836
|
+
# Post.joins(:comments).structurally_compatible?(Post.where("id = 1"))
|
837
|
+
# # => false
|
838
|
+
#
|
839
|
+
def structurally_compatible?(other)
|
840
|
+
structurally_incompatible_values_for(other).empty?
|
841
|
+
end
|
842
|
+
|
671
843
|
# Returns a new relation, which is the logical intersection of this relation and the one passed
|
672
844
|
# as an argument.
|
673
845
|
#
|
@@ -886,7 +1058,7 @@ module ActiveRecord
|
|
886
1058
|
self
|
887
1059
|
end
|
888
1060
|
|
889
|
-
# Specifies table from which the records will be fetched. For example:
|
1061
|
+
# Specifies the table from which the records will be fetched. For example:
|
890
1062
|
#
|
891
1063
|
# Topic.select('title').from('posts')
|
892
1064
|
# # SELECT title FROM posts
|
@@ -896,9 +1068,26 @@ module ActiveRecord
|
|
896
1068
|
# Topic.select('title').from(Topic.approved)
|
897
1069
|
# # SELECT title FROM (SELECT * FROM topics WHERE approved = 't') subquery
|
898
1070
|
#
|
1071
|
+
# Passing a second argument (string or symbol), creates the alias for the SQL from clause. Otherwise the alias "subquery" is used:
|
1072
|
+
#
|
899
1073
|
# Topic.select('a.title').from(Topic.approved, :a)
|
900
1074
|
# # SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a
|
901
1075
|
#
|
1076
|
+
# It does not add multiple arguments to the SQL from clause. The last +from+ chained is the one used:
|
1077
|
+
#
|
1078
|
+
# Topic.select('title').from(Topic.approved).from(Topic.inactive)
|
1079
|
+
# # SELECT title FROM (SELECT topics.* FROM topics WHERE topics.active = 'f') subquery
|
1080
|
+
#
|
1081
|
+
# For multiple arguments for the SQL from clause, you can pass a string with the exact elements in the SQL from list:
|
1082
|
+
#
|
1083
|
+
# color = "red"
|
1084
|
+
# Color
|
1085
|
+
# .from("colors c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")
|
1086
|
+
# .where("colorvalue->>'color' = ?", color)
|
1087
|
+
# .select("c.*").to_a
|
1088
|
+
# # SELECT c.*
|
1089
|
+
# # FROM colors c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)
|
1090
|
+
# # WHERE (colorvalue->>'color' = 'red')
|
902
1091
|
def from(value, subquery_name = nil)
|
903
1092
|
spawn.from!(value, subquery_name)
|
904
1093
|
end
|
@@ -994,7 +1183,7 @@ module ActiveRecord
|
|
994
1183
|
# Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
|
995
1184
|
# # SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
|
996
1185
|
def optimizer_hints(*args)
|
997
|
-
check_if_method_has_arguments!(
|
1186
|
+
check_if_method_has_arguments!(__callee__, args)
|
998
1187
|
spawn.optimizer_hints!(*args)
|
999
1188
|
end
|
1000
1189
|
|
@@ -1038,7 +1227,7 @@ module ActiveRecord
|
|
1038
1227
|
#
|
1039
1228
|
# Some escaping is performed, however untrusted user input should not be used.
|
1040
1229
|
def annotate(*args)
|
1041
|
-
check_if_method_has_arguments!(
|
1230
|
+
check_if_method_has_arguments!(__callee__, args)
|
1042
1231
|
spawn.annotate!(*args)
|
1043
1232
|
end
|
1044
1233
|
|
@@ -1056,6 +1245,47 @@ module ActiveRecord
|
|
1056
1245
|
self
|
1057
1246
|
end
|
1058
1247
|
|
1248
|
+
# Excludes the specified record (or collection of records) from the resulting
|
1249
|
+
# relation. For example:
|
1250
|
+
#
|
1251
|
+
# Post.excluding(post)
|
1252
|
+
# # SELECT "posts".* FROM "posts" WHERE "posts"."id" != 1
|
1253
|
+
#
|
1254
|
+
# Post.excluding(post_one, post_two)
|
1255
|
+
# # SELECT "posts".* FROM "posts" WHERE "posts"."id" NOT IN (1, 2)
|
1256
|
+
#
|
1257
|
+
# This can also be called on associations. As with the above example, either
|
1258
|
+
# a single record of collection thereof may be specified:
|
1259
|
+
#
|
1260
|
+
# post = Post.find(1)
|
1261
|
+
# comment = Comment.find(2)
|
1262
|
+
# post.comments.excluding(comment)
|
1263
|
+
# # SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1 AND "comments"."id" != 2
|
1264
|
+
#
|
1265
|
+
# This is short-hand for <tt>.where.not(id: post.id)</tt> and <tt>.where.not(id: [post_one.id, post_two.id])</tt>.
|
1266
|
+
#
|
1267
|
+
# An <tt>ArgumentError</tt> will be raised if either no records are
|
1268
|
+
# specified, or if any of the records in the collection (if a collection
|
1269
|
+
# is passed in) are not instances of the same model that the relation is
|
1270
|
+
# scoping.
|
1271
|
+
def excluding(*records)
|
1272
|
+
records.flatten!(1)
|
1273
|
+
records.compact!
|
1274
|
+
|
1275
|
+
unless records.all?(klass)
|
1276
|
+
raise ArgumentError, "You must only pass a single or collection of #{klass.name} objects to ##{__callee__}."
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
spawn.excluding!(records)
|
1280
|
+
end
|
1281
|
+
alias :without :excluding
|
1282
|
+
|
1283
|
+
def excluding!(records) # :nodoc:
|
1284
|
+
predicates = [ predicate_builder[primary_key, records].invert ]
|
1285
|
+
self.where_clause += Relation::WhereClause.new(predicates)
|
1286
|
+
self
|
1287
|
+
end
|
1288
|
+
|
1059
1289
|
# Returns the Arel object associated with the relation.
|
1060
1290
|
def arel(aliases = nil) # :nodoc:
|
1061
1291
|
@arel ||= build_arel(aliases)
|
@@ -1111,11 +1341,9 @@ module ActiveRecord
|
|
1111
1341
|
nil
|
1112
1342
|
end
|
1113
1343
|
|
1114
|
-
def each_join_dependencies(join_dependencies = build_join_dependencies)
|
1344
|
+
def each_join_dependencies(join_dependencies = build_join_dependencies, &block)
|
1115
1345
|
join_dependencies.each do |join_dependency|
|
1116
|
-
join_dependency.each
|
1117
|
-
yield join
|
1118
|
-
end
|
1346
|
+
join_dependency.each(&block)
|
1119
1347
|
end
|
1120
1348
|
end
|
1121
1349
|
|
@@ -1157,14 +1385,6 @@ module ActiveRecord
|
|
1157
1385
|
unless annotate_values.empty?
|
1158
1386
|
annotates = annotate_values
|
1159
1387
|
annotates = annotates.uniq if annotates.size > 1
|
1160
|
-
unless annotates == annotate_values
|
1161
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
1162
|
-
Duplicated query annotations are no longer shown in queries in Rails 7.0.
|
1163
|
-
To migrate to Rails 7.0's behavior, use `uniq!(:annotate)` to deduplicate query annotations
|
1164
|
-
(`#{klass.name&.tableize || klass.table_name}.uniq!(:annotate)`).
|
1165
|
-
MSG
|
1166
|
-
annotates = annotate_values
|
1167
|
-
end
|
1168
1388
|
arel.comment(*annotates)
|
1169
1389
|
end
|
1170
1390
|
|
@@ -1172,8 +1392,7 @@ module ActiveRecord
|
|
1172
1392
|
end
|
1173
1393
|
|
1174
1394
|
def build_cast_value(name, value)
|
1175
|
-
|
1176
|
-
Arel::Nodes::BindParam.new(cast_value)
|
1395
|
+
ActiveModel::Attribute.with_cast_value(name, value, Type.default_value)
|
1177
1396
|
end
|
1178
1397
|
|
1179
1398
|
def build_from
|
@@ -1284,7 +1503,7 @@ module ActiveRecord
|
|
1284
1503
|
def build_select(arel)
|
1285
1504
|
if select_values.any?
|
1286
1505
|
arel.project(*arel_columns(select_values))
|
1287
|
-
elsif klass.ignored_columns.any?
|
1506
|
+
elsif klass.ignored_columns.any? || klass.enumerate_columns_in_select_statements
|
1288
1507
|
arel.project(*klass.column_names.map { |field| table[field] })
|
1289
1508
|
else
|
1290
1509
|
arel.project(table[Arel.star])
|
@@ -1425,12 +1644,17 @@ module ActiveRecord
|
|
1425
1644
|
order_args.map! do |arg|
|
1426
1645
|
klass.sanitize_sql_for_order(arg)
|
1427
1646
|
end
|
1428
|
-
order_args.flatten!
|
1429
|
-
order_args.compact_blank!
|
1430
1647
|
end
|
1431
1648
|
|
1432
1649
|
def column_references(order_args)
|
1433
|
-
references = order_args.
|
1650
|
+
references = order_args.flat_map do |arg|
|
1651
|
+
case arg
|
1652
|
+
when String, Symbol
|
1653
|
+
arg
|
1654
|
+
when Hash
|
1655
|
+
arg.keys
|
1656
|
+
end
|
1657
|
+
end
|
1434
1658
|
references.map! { |arg| arg =~ /^\W?(\w+)\W?\./ && $1 }.compact!
|
1435
1659
|
references
|
1436
1660
|
end
|
@@ -1478,19 +1702,19 @@ module ActiveRecord
|
|
1478
1702
|
# Post.references() # raises an error
|
1479
1703
|
# Post.references([]) # does not raise an error
|
1480
1704
|
#
|
1481
|
-
# This particular method should be called with a method_name and the args
|
1705
|
+
# This particular method should be called with a method_name (__callee__) and the args
|
1482
1706
|
# passed into that method as an input. For example:
|
1483
1707
|
#
|
1484
1708
|
# def references(*args)
|
1485
|
-
# check_if_method_has_arguments!(
|
1709
|
+
# check_if_method_has_arguments!(__callee__, args)
|
1486
1710
|
# ...
|
1487
1711
|
# end
|
1488
1712
|
def check_if_method_has_arguments!(method_name, args, message = nil)
|
1489
1713
|
if args.blank?
|
1490
1714
|
raise ArgumentError, message || "The method .#{method_name}() must contain arguments."
|
1491
|
-
elsif block_given?
|
1492
|
-
yield args
|
1493
1715
|
else
|
1716
|
+
yield args if block_given?
|
1717
|
+
|
1494
1718
|
args.flatten!
|
1495
1719
|
args.compact_blank!
|
1496
1720
|
end
|
@@ -1514,11 +1738,4 @@ module ActiveRecord
|
|
1514
1738
|
end
|
1515
1739
|
end
|
1516
1740
|
end
|
1517
|
-
|
1518
|
-
class Relation # :nodoc:
|
1519
|
-
# No-op WhereClauseFactory to work Mashal.load(File.read("legacy_relation.dump")).
|
1520
|
-
# TODO: Remove the class once Rails 6.1 has released.
|
1521
|
-
class WhereClauseFactory # :nodoc:
|
1522
|
-
end
|
1523
|
-
end
|
1524
1741
|
end
|