activerecord 6.1.7.6 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1055 -1180
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- 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 +18 -19
- data/lib/active_record/associations/collection_proxy.rb +8 -3
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +10 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +6 -2
- 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 +49 -13
- data/lib/active_record/associations/preloader.rb +39 -113
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +90 -82
- 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 +7 -5
- data/lib/active_record/attribute_methods/serialization.rb +66 -12
- 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 +13 -14
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +6 -21
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +2 -14
- 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 +43 -82
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +34 -13
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +69 -18
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
- data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +97 -81
- data/lib/active_record/connection_adapters/column.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +35 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +35 -21
- 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 +17 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -12
- 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 +28 -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 +50 -76
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -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 +27 -16
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -107
- 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 +15 -16
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +47 -53
- data/lib/active_record/core.rb +121 -146
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -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 +52 -11
- 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 +61 -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 +208 -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 +49 -42
- data/lib/active_record/errors.rb +67 -4
- data/lib/active_record/explain_registry.rb +11 -6
- 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 +17 -20
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +4 -4
- 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 +10 -9
- data/lib/active_record/locking/pessimistic.rb +9 -3
- data/lib/active_record/log_subscriber.rb +14 -3
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +8 -3
- data/lib/active_record/middleware/shard_selector.rb +60 -0
- data/lib/active_record/migration/command_recorder.rb +4 -4
- data/lib/active_record/migration/compatibility.rb +89 -10
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +110 -80
- data/lib/active_record/model_schema.rb +45 -58
- 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 +219 -52
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +138 -0
- data/lib/active_record/querying.rb +15 -5
- data/lib/active_record/railtie.rb +127 -17
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +66 -129
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +67 -50
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +40 -36
- data/lib/active_record/relation/delegation.rb +6 -6
- 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.rb +1 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +235 -63
- 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 +169 -84
- data/lib/active_record/result.rb +17 -7
- data/lib/active_record/runtime_registry.rb +9 -13
- data/lib/active_record/sanitization.rb +11 -7
- data/lib/active_record/schema_dumper.rb +10 -3
- data/lib/active_record/schema_migration.rb +4 -4
- data/lib/active_record/scoping/default.rb +61 -12
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +64 -34
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/store.rb +1 -6
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/tasks/database_tasks.rb +116 -58
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -12
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +9 -13
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +2 -2
- 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 +1 -1
- 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 +1 -1
- data/lib/active_record/validations/uniqueness.rb +1 -1
- data/lib/active_record.rb +204 -28
- 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
@@ -51,30 +51,25 @@ module ActiveRecord
|
|
51
51
|
@rewhere = rewhere
|
52
52
|
end
|
53
53
|
|
54
|
-
NORMAL_VALUES = Relation::VALUE_METHODS -
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
NORMAL_VALUES
|
60
|
-
end
|
54
|
+
NORMAL_VALUES = Relation::VALUE_METHODS - Relation::CLAUSE_METHODS -
|
55
|
+
[
|
56
|
+
:select, :includes, :preload, :joins, :left_outer_joins,
|
57
|
+
:order, :reverse_order, :lock, :create_with, :reordering
|
58
|
+
]
|
61
59
|
|
62
60
|
def merge
|
63
|
-
|
61
|
+
NORMAL_VALUES.each do |name|
|
64
62
|
value = values[name]
|
65
63
|
# The unless clause is here mostly for performance reasons (since the `send` call might be moderately
|
66
64
|
# expensive), most of the time the value is going to be `nil` or `.blank?`, the only catch is that
|
67
65
|
# `false.blank?` returns `true`, so there needs to be an extra check so that explicit `false` values
|
68
66
|
# don't fall through the cracks.
|
69
67
|
unless value.nil? || (value.blank? && false != value)
|
70
|
-
|
71
|
-
relation._select!(*value)
|
72
|
-
else
|
73
|
-
relation.public_send("#{name}!", *value)
|
74
|
-
end
|
68
|
+
relation.public_send(:"#{name}!", *value)
|
75
69
|
end
|
76
70
|
end
|
77
71
|
|
72
|
+
merge_select_values
|
78
73
|
merge_multi_values
|
79
74
|
merge_single_values
|
80
75
|
merge_clauses
|
@@ -86,6 +81,18 @@ module ActiveRecord
|
|
86
81
|
end
|
87
82
|
|
88
83
|
private
|
84
|
+
def merge_select_values
|
85
|
+
return if other.select_values.empty?
|
86
|
+
|
87
|
+
if other.klass == relation.klass
|
88
|
+
relation.select_values |= other.select_values
|
89
|
+
else
|
90
|
+
relation.select_values |= other.instance_eval do
|
91
|
+
arel_columns(select_values)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
89
96
|
def merge_preloads
|
90
97
|
return if other.preload_values.empty? && other.includes_values.empty?
|
91
98
|
|
@@ -9,10 +9,6 @@ module ActiveRecord
|
|
9
9
|
require "active_record/relation/predicate_builder/association_query_value"
|
10
10
|
require "active_record/relation/predicate_builder/polymorphic_array_value"
|
11
11
|
|
12
|
-
# No-op BaseHandler to work Mashal.load(File.read("legacy_relation.dump")).
|
13
|
-
# TODO: Remove the constant alias once Rails 6.1 has released.
|
14
|
-
BaseHandler = BasicObjectHandler
|
15
|
-
|
16
12
|
def initialize(table)
|
17
13
|
@table = table
|
18
14
|
@handlers = []
|
@@ -69,8 +65,7 @@ module ActiveRecord
|
|
69
65
|
end
|
70
66
|
|
71
67
|
def build_bind_attribute(column_name, value)
|
72
|
-
|
73
|
-
Arel::Nodes::BindParam.new(attr)
|
68
|
+
Relation::QueryAttribute.new(column_name, value, table.type(column_name))
|
74
69
|
end
|
75
70
|
|
76
71
|
def resolve_arel_attribute(table_name, column_name, &block)
|
@@ -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,8 +8,6 @@ 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
13
|
# WhereChain objects act as placeholder for queries in which #where does not have any parameter.
|
@@ -50,6 +48,34 @@ module ActiveRecord
|
|
50
48
|
@scope
|
51
49
|
end
|
52
50
|
|
51
|
+
# Returns a new relation with joins and where clause to identify
|
52
|
+
# associated relations.
|
53
|
+
#
|
54
|
+
# For example, posts that are associated to a related author:
|
55
|
+
#
|
56
|
+
# Post.where.associated(:author)
|
57
|
+
# # SELECT "posts".* FROM "posts"
|
58
|
+
# # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
|
59
|
+
# # WHERE "authors"."id" IS NOT NULL
|
60
|
+
#
|
61
|
+
# Additionally, multiple relations can be combined. This will return posts
|
62
|
+
# associated to both an author and any comments:
|
63
|
+
#
|
64
|
+
# Post.where.associated(:author, :comments)
|
65
|
+
# # SELECT "posts".* FROM "posts"
|
66
|
+
# # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
|
67
|
+
# # INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
68
|
+
# # WHERE "authors"."id" IS NOT NULL AND "comments"."id" IS NOT NULL
|
69
|
+
def associated(*associations)
|
70
|
+
associations.each do |association|
|
71
|
+
reflection = @scope.klass._reflect_on_association(association)
|
72
|
+
@scope.joins!(association)
|
73
|
+
self.not(reflection.table_name => { reflection.association_primary_key => nil })
|
74
|
+
end
|
75
|
+
|
76
|
+
@scope
|
77
|
+
end
|
78
|
+
|
53
79
|
# Returns a new relation with left outer joins and where clause to identify
|
54
80
|
# missing relations.
|
55
81
|
#
|
@@ -68,12 +94,11 @@ module ActiveRecord
|
|
68
94
|
# # LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
|
69
95
|
# # LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
|
70
96
|
# # WHERE "authors"."id" IS NULL AND "comments"."id" IS NULL
|
71
|
-
def missing(*
|
72
|
-
|
73
|
-
reflection = @scope.klass._reflect_on_association(
|
74
|
-
|
75
|
-
@scope.
|
76
|
-
@scope.where!(opts)
|
97
|
+
def missing(*associations)
|
98
|
+
associations.each do |association|
|
99
|
+
reflection = @scope.klass._reflect_on_association(association)
|
100
|
+
@scope.left_outer_joins!(association)
|
101
|
+
@scope.where!(reflection.table_name => { reflection.association_primary_key => nil })
|
77
102
|
end
|
78
103
|
|
79
104
|
@scope
|
@@ -148,7 +173,7 @@ module ActiveRecord
|
|
148
173
|
#
|
149
174
|
# User.includes(:posts).where(posts: { name: 'example' })
|
150
175
|
def includes(*args)
|
151
|
-
check_if_method_has_arguments!(
|
176
|
+
check_if_method_has_arguments!(__callee__, args)
|
152
177
|
spawn.includes!(*args)
|
153
178
|
end
|
154
179
|
|
@@ -164,7 +189,7 @@ module ActiveRecord
|
|
164
189
|
# # FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" =
|
165
190
|
# # "users"."id"
|
166
191
|
def eager_load(*args)
|
167
|
-
check_if_method_has_arguments!(
|
192
|
+
check_if_method_has_arguments!(__callee__, args)
|
168
193
|
spawn.eager_load!(*args)
|
169
194
|
end
|
170
195
|
|
@@ -178,7 +203,7 @@ module ActiveRecord
|
|
178
203
|
# User.preload(:posts)
|
179
204
|
# # SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3)
|
180
205
|
def preload(*args)
|
181
|
-
check_if_method_has_arguments!(
|
206
|
+
check_if_method_has_arguments!(__callee__, args)
|
182
207
|
spawn.preload!(*args)
|
183
208
|
end
|
184
209
|
|
@@ -211,7 +236,7 @@ module ActiveRecord
|
|
211
236
|
# User.includes(:posts).where("posts.name = 'foo'").references(:posts)
|
212
237
|
# # Query now knows the string references posts, so adds a JOIN
|
213
238
|
def references(*table_names)
|
214
|
-
check_if_method_has_arguments!(
|
239
|
+
check_if_method_has_arguments!(__callee__, table_names)
|
215
240
|
spawn.references!(*table_names)
|
216
241
|
end
|
217
242
|
|
@@ -269,7 +294,7 @@ module ActiveRecord
|
|
269
294
|
return super()
|
270
295
|
end
|
271
296
|
|
272
|
-
check_if_method_has_arguments!(
|
297
|
+
check_if_method_has_arguments!(__callee__, fields, "Call `select' with at least one field.")
|
273
298
|
spawn._select!(*fields)
|
274
299
|
end
|
275
300
|
|
@@ -289,7 +314,7 @@ module ActiveRecord
|
|
289
314
|
# This is short-hand for <tt>unscope(:select).select(fields)</tt>.
|
290
315
|
# Note that we're unscoping the entire select statement.
|
291
316
|
def reselect(*args)
|
292
|
-
check_if_method_has_arguments!(
|
317
|
+
check_if_method_has_arguments!(__callee__, args)
|
293
318
|
spawn.reselect!(*args)
|
294
319
|
end
|
295
320
|
|
@@ -320,7 +345,7 @@ module ActiveRecord
|
|
320
345
|
# User.select([:id, :first_name]).group(:id, :first_name).first(3)
|
321
346
|
# # => [#<User id: 1, first_name: "Bill">, #<User id: 2, first_name: "Earl">, #<User id: 3, first_name: "Beto">]
|
322
347
|
def group(*args)
|
323
|
-
check_if_method_has_arguments!(
|
348
|
+
check_if_method_has_arguments!(__callee__, args)
|
324
349
|
spawn.group!(*args)
|
325
350
|
end
|
326
351
|
|
@@ -329,17 +354,37 @@ module ActiveRecord
|
|
329
354
|
self
|
330
355
|
end
|
331
356
|
|
332
|
-
#
|
357
|
+
# Applies an <code>ORDER BY</code> clause to a query.
|
358
|
+
#
|
359
|
+
# #order accepts arguments in one of several formats.
|
360
|
+
#
|
361
|
+
# === symbols
|
362
|
+
#
|
363
|
+
# The symbol represents the name of the column you want to order the results by.
|
333
364
|
#
|
334
365
|
# User.order(:name)
|
335
366
|
# # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC
|
336
367
|
#
|
368
|
+
# By default, the order is ascending. If you want descending order, you can
|
369
|
+
# map the column name symbol to +:desc+.
|
370
|
+
#
|
337
371
|
# User.order(email: :desc)
|
338
372
|
# # SELECT "users".* FROM "users" ORDER BY "users"."email" DESC
|
339
373
|
#
|
374
|
+
# Multiple columns can be passed this way, and they will be applied in the order specified.
|
375
|
+
#
|
340
376
|
# User.order(:name, email: :desc)
|
341
377
|
# # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC
|
342
378
|
#
|
379
|
+
# === strings
|
380
|
+
#
|
381
|
+
# Strings are passed directly to the database, allowing you to specify
|
382
|
+
# simple SQL expressions.
|
383
|
+
#
|
384
|
+
# This could be a source of SQL injection, so only strings composed of plain
|
385
|
+
# column names and simple <code>function(column_name)</code> expressions
|
386
|
+
# with optional +ASC+/+DESC+ modifiers are allowed.
|
387
|
+
#
|
343
388
|
# User.order('name')
|
344
389
|
# # SELECT "users".* FROM "users" ORDER BY name
|
345
390
|
#
|
@@ -348,8 +393,21 @@ module ActiveRecord
|
|
348
393
|
#
|
349
394
|
# User.order('name DESC, email')
|
350
395
|
# # SELECT "users".* FROM "users" ORDER BY name DESC, email
|
396
|
+
#
|
397
|
+
# === Arel
|
398
|
+
#
|
399
|
+
# If you need to pass in complicated expressions that you have verified
|
400
|
+
# are safe for the database, you can use Arel.
|
401
|
+
#
|
402
|
+
# User.order(Arel.sql('end_date - start_date'))
|
403
|
+
# # SELECT "users".* FROM "users" ORDER BY end_date - start_date
|
404
|
+
#
|
405
|
+
# Custom query syntax, like JSON columns for Postgres, is supported in this way.
|
406
|
+
#
|
407
|
+
# User.order(Arel.sql("payload->>'kind'"))
|
408
|
+
# # SELECT "users".* FROM "users" ORDER BY payload->>'kind'
|
351
409
|
def order(*args)
|
352
|
-
check_if_method_has_arguments!(
|
410
|
+
check_if_method_has_arguments!(__callee__, args) do
|
353
411
|
sanitize_order_arguments(args)
|
354
412
|
end
|
355
413
|
spawn.order!(*args)
|
@@ -362,6 +420,24 @@ module ActiveRecord
|
|
362
420
|
self
|
363
421
|
end
|
364
422
|
|
423
|
+
# Allows to specify an order by a specific set of values. Depending on your
|
424
|
+
# adapter this will either use a CASE statement or a built-in function.
|
425
|
+
#
|
426
|
+
# User.in_order_of(:id, [1, 5, 3])
|
427
|
+
# # SELECT "users".* FROM "users" ORDER BY FIELD("users"."id", 1, 5, 3)
|
428
|
+
#
|
429
|
+
def in_order_of(column, values)
|
430
|
+
klass.disallow_raw_sql!([column], permit: connection.column_name_with_order_matcher)
|
431
|
+
|
432
|
+
references = column_references([column])
|
433
|
+
self.references_values |= references unless references.empty?
|
434
|
+
|
435
|
+
values = values.map { |value| type_caster.type_cast_for_database(column, value) }
|
436
|
+
column = order_column(column.to_s) if column.is_a?(Symbol)
|
437
|
+
|
438
|
+
spawn.order!(connection.field_ordered_value(column, values))
|
439
|
+
end
|
440
|
+
|
365
441
|
# Replaces any existing order defined on the relation with the specified order.
|
366
442
|
#
|
367
443
|
# User.order('email DESC').reorder('id ASC') # generated SQL has 'ORDER BY id ASC'
|
@@ -372,15 +448,15 @@ module ActiveRecord
|
|
372
448
|
#
|
373
449
|
# generates a query with 'ORDER BY id ASC, name ASC'.
|
374
450
|
def reorder(*args)
|
375
|
-
check_if_method_has_arguments!(
|
376
|
-
sanitize_order_arguments(args)
|
451
|
+
check_if_method_has_arguments!(__callee__, args) do
|
452
|
+
sanitize_order_arguments(args)
|
377
453
|
end
|
378
454
|
spawn.reorder!(*args)
|
379
455
|
end
|
380
456
|
|
381
457
|
# Same as #reorder but operates on relation in-place instead of copying.
|
382
458
|
def reorder!(*args) # :nodoc:
|
383
|
-
preprocess_order_args(args)
|
459
|
+
preprocess_order_args(args)
|
384
460
|
args.uniq!
|
385
461
|
self.reordering_value = true
|
386
462
|
self.order_values = args
|
@@ -425,7 +501,7 @@ module ActiveRecord
|
|
425
501
|
# has_many :comments, -> { unscope(where: :trashed) }
|
426
502
|
#
|
427
503
|
def unscope(*args)
|
428
|
-
check_if_method_has_arguments!(
|
504
|
+
check_if_method_has_arguments!(__callee__, args)
|
429
505
|
spawn.unscope!(*args)
|
430
506
|
end
|
431
507
|
|
@@ -458,7 +534,7 @@ module ActiveRecord
|
|
458
534
|
self
|
459
535
|
end
|
460
536
|
|
461
|
-
# Performs
|
537
|
+
# Performs JOINs on +args+. The given symbol(s) should match the name of
|
462
538
|
# the association(s).
|
463
539
|
#
|
464
540
|
# User.joins(:posts)
|
@@ -487,7 +563,7 @@ module ActiveRecord
|
|
487
563
|
# User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id")
|
488
564
|
# # SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
|
489
565
|
def joins(*args)
|
490
|
-
check_if_method_has_arguments!(
|
566
|
+
check_if_method_has_arguments!(__callee__, args)
|
491
567
|
spawn.joins!(*args)
|
492
568
|
end
|
493
569
|
|
@@ -496,7 +572,7 @@ module ActiveRecord
|
|
496
572
|
self
|
497
573
|
end
|
498
574
|
|
499
|
-
# Performs
|
575
|
+
# Performs LEFT OUTER JOINs on +args+:
|
500
576
|
#
|
501
577
|
# User.left_outer_joins(:posts)
|
502
578
|
# => SELECT "users".* FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
|
@@ -578,13 +654,13 @@ module ActiveRecord
|
|
578
654
|
#
|
579
655
|
# Fields can be symbols or strings. Values can be single values, arrays, or ranges.
|
580
656
|
#
|
581
|
-
# User.where(
|
657
|
+
# User.where(name: "Joe", email: "joe@example.com")
|
582
658
|
# # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'
|
583
659
|
#
|
584
|
-
# User.where(
|
660
|
+
# User.where(name: ["Alice", "Bob"])
|
585
661
|
# # SELECT * FROM users WHERE name IN ('Alice', 'Bob')
|
586
662
|
#
|
587
|
-
# User.where(
|
663
|
+
# User.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
|
588
664
|
# # SELECT * FROM users WHERE (created_at BETWEEN '2012-06-09 07:00:00.000000' AND '2012-06-10 07:00:00.000000')
|
589
665
|
#
|
590
666
|
# In the case of a belongs_to relationship, an association key can be used
|
@@ -614,8 +690,8 @@ module ActiveRecord
|
|
614
690
|
#
|
615
691
|
# For hash conditions, you can either use the table name in the key, or use a sub-hash.
|
616
692
|
#
|
617
|
-
# User.joins(:posts).where(
|
618
|
-
# User.joins(:posts).where(
|
693
|
+
# User.joins(:posts).where("posts.published" => true)
|
694
|
+
# User.joins(:posts).where(posts: { published: true })
|
619
695
|
#
|
620
696
|
# === no argument
|
621
697
|
#
|
@@ -668,6 +744,59 @@ module ActiveRecord
|
|
668
744
|
scope
|
669
745
|
end
|
670
746
|
|
747
|
+
# Allows you to invert an entire where clause instead of manually applying conditions.
|
748
|
+
#
|
749
|
+
# class User
|
750
|
+
# scope :active, -> { where(accepted: true, locked: false) }
|
751
|
+
# end
|
752
|
+
#
|
753
|
+
# User.where(accepted: true)
|
754
|
+
# # WHERE `accepted` = 1
|
755
|
+
#
|
756
|
+
# User.where(accepted: true).invert_where
|
757
|
+
# # WHERE `accepted` != 1
|
758
|
+
#
|
759
|
+
# User.active
|
760
|
+
# # WHERE `accepted` = 1 AND `locked` = 0
|
761
|
+
#
|
762
|
+
# User.active.invert_where
|
763
|
+
# # WHERE NOT (`accepted` = 1 AND `locked` = 0)
|
764
|
+
#
|
765
|
+
# Be careful because this inverts all conditions before +invert_where+ call.
|
766
|
+
#
|
767
|
+
# class User
|
768
|
+
# scope :active, -> { where(accepted: true, locked: false) }
|
769
|
+
# scope :inactive, -> { active.invert_where } # Do not attempt it
|
770
|
+
# end
|
771
|
+
#
|
772
|
+
# # It also inverts `where(role: 'admin')` unexpectedly.
|
773
|
+
# User.where(role: 'admin').inactive
|
774
|
+
# # WHERE NOT (`role` = 'admin' AND `accepted` = 1 AND `locked` = 0)
|
775
|
+
#
|
776
|
+
def invert_where
|
777
|
+
spawn.invert_where!
|
778
|
+
end
|
779
|
+
|
780
|
+
def invert_where! # :nodoc:
|
781
|
+
self.where_clause = where_clause.invert
|
782
|
+
self
|
783
|
+
end
|
784
|
+
|
785
|
+
# Checks whether the given relation is structurally compatible with this relation, to determine
|
786
|
+
# if it's possible to use the #and and #or methods without raising an error. Structurally
|
787
|
+
# compatible is defined as: they must be scoping the same model, and they must differ only by
|
788
|
+
# #where (if no #group has been defined) or #having (if a #group is present).
|
789
|
+
#
|
790
|
+
# Post.where("id = 1").structurally_compatible?(Post.where("author_id = 3"))
|
791
|
+
# # => true
|
792
|
+
#
|
793
|
+
# Post.joins(:comments).structurally_compatible?(Post.where("id = 1"))
|
794
|
+
# # => false
|
795
|
+
#
|
796
|
+
def structurally_compatible?(other)
|
797
|
+
structurally_incompatible_values_for(other).empty?
|
798
|
+
end
|
799
|
+
|
671
800
|
# Returns a new relation, which is the logical intersection of this relation and the one passed
|
672
801
|
# as an argument.
|
673
802
|
#
|
@@ -886,7 +1015,7 @@ module ActiveRecord
|
|
886
1015
|
self
|
887
1016
|
end
|
888
1017
|
|
889
|
-
# Specifies table from which the records will be fetched. For example:
|
1018
|
+
# Specifies the table from which the records will be fetched. For example:
|
890
1019
|
#
|
891
1020
|
# Topic.select('title').from('posts')
|
892
1021
|
# # SELECT title FROM posts
|
@@ -896,9 +1025,26 @@ module ActiveRecord
|
|
896
1025
|
# Topic.select('title').from(Topic.approved)
|
897
1026
|
# # SELECT title FROM (SELECT * FROM topics WHERE approved = 't') subquery
|
898
1027
|
#
|
1028
|
+
# Passing a second argument (string or symbol), creates the alias for the SQL from clause. Otherwise the alias "subquery" is used:
|
1029
|
+
#
|
899
1030
|
# Topic.select('a.title').from(Topic.approved, :a)
|
900
1031
|
# # SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a
|
901
1032
|
#
|
1033
|
+
# It does not add multiple arguments to the SQL from clause. The last +from+ chained is the one used:
|
1034
|
+
#
|
1035
|
+
# Topic.select('title').from(Topic.approved).from(Topic.inactive)
|
1036
|
+
# # SELECT title FROM (SELECT topics.* FROM topics WHERE topics.active = 'f') subquery
|
1037
|
+
#
|
1038
|
+
# For multiple arguments for the SQL from clause, you can pass a string with the exact elements in the SQL from list:
|
1039
|
+
#
|
1040
|
+
# color = "red"
|
1041
|
+
# Color
|
1042
|
+
# .from("colors c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")
|
1043
|
+
# .where("colorvalue->>'color' = ?", color)
|
1044
|
+
# .select("c.*").to_a
|
1045
|
+
# # SELECT c.*
|
1046
|
+
# # FROM colors c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)
|
1047
|
+
# # WHERE (colorvalue->>'color' = 'red')
|
902
1048
|
def from(value, subquery_name = nil)
|
903
1049
|
spawn.from!(value, subquery_name)
|
904
1050
|
end
|
@@ -994,7 +1140,7 @@ module ActiveRecord
|
|
994
1140
|
# Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
|
995
1141
|
# # SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
|
996
1142
|
def optimizer_hints(*args)
|
997
|
-
check_if_method_has_arguments!(
|
1143
|
+
check_if_method_has_arguments!(__callee__, args)
|
998
1144
|
spawn.optimizer_hints!(*args)
|
999
1145
|
end
|
1000
1146
|
|
@@ -1035,10 +1181,8 @@ module ActiveRecord
|
|
1035
1181
|
# # SELECT "users"."name" FROM "users" /* selecting */ /* user */ /* names */
|
1036
1182
|
#
|
1037
1183
|
# The SQL block comment delimiters, "/*" and "*/", will be added automatically.
|
1038
|
-
#
|
1039
|
-
# Some escaping is performed, however untrusted user input should not be used.
|
1040
1184
|
def annotate(*args)
|
1041
|
-
check_if_method_has_arguments!(
|
1185
|
+
check_if_method_has_arguments!(__callee__, args)
|
1042
1186
|
spawn.annotate!(*args)
|
1043
1187
|
end
|
1044
1188
|
|
@@ -1056,6 +1200,47 @@ module ActiveRecord
|
|
1056
1200
|
self
|
1057
1201
|
end
|
1058
1202
|
|
1203
|
+
# Excludes the specified record (or collection of records) from the resulting
|
1204
|
+
# relation. For example:
|
1205
|
+
#
|
1206
|
+
# Post.excluding(post)
|
1207
|
+
# # SELECT "posts".* FROM "posts" WHERE "posts"."id" != 1
|
1208
|
+
#
|
1209
|
+
# Post.excluding(post_one, post_two)
|
1210
|
+
# # SELECT "posts".* FROM "posts" WHERE "posts"."id" NOT IN (1, 2)
|
1211
|
+
#
|
1212
|
+
# This can also be called on associations. As with the above example, either
|
1213
|
+
# a single record of collection thereof may be specified:
|
1214
|
+
#
|
1215
|
+
# post = Post.find(1)
|
1216
|
+
# comment = Comment.find(2)
|
1217
|
+
# post.comments.excluding(comment)
|
1218
|
+
# # SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1 AND "comments"."id" != 2
|
1219
|
+
#
|
1220
|
+
# This is short-hand for <tt>.where.not(id: post.id)</tt> and <tt>.where.not(id: [post_one.id, post_two.id])</tt>.
|
1221
|
+
#
|
1222
|
+
# An <tt>ArgumentError</tt> will be raised if either no records are
|
1223
|
+
# specified, or if any of the records in the collection (if a collection
|
1224
|
+
# is passed in) are not instances of the same model that the relation is
|
1225
|
+
# scoping.
|
1226
|
+
def excluding(*records)
|
1227
|
+
records.flatten!(1)
|
1228
|
+
records.compact!
|
1229
|
+
|
1230
|
+
unless records.all?(klass)
|
1231
|
+
raise ArgumentError, "You must only pass a single or collection of #{klass.name} objects to ##{__callee__}."
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
spawn.excluding!(records)
|
1235
|
+
end
|
1236
|
+
alias :without :excluding
|
1237
|
+
|
1238
|
+
def excluding!(records) # :nodoc:
|
1239
|
+
predicates = [ predicate_builder[primary_key, records].invert ]
|
1240
|
+
self.where_clause += Relation::WhereClause.new(predicates)
|
1241
|
+
self
|
1242
|
+
end
|
1243
|
+
|
1059
1244
|
# Returns the Arel object associated with the relation.
|
1060
1245
|
def arel(aliases = nil) # :nodoc:
|
1061
1246
|
@arel ||= build_arel(aliases)
|
@@ -1111,11 +1296,9 @@ module ActiveRecord
|
|
1111
1296
|
nil
|
1112
1297
|
end
|
1113
1298
|
|
1114
|
-
def each_join_dependencies(join_dependencies = build_join_dependencies)
|
1299
|
+
def each_join_dependencies(join_dependencies = build_join_dependencies, &block)
|
1115
1300
|
join_dependencies.each do |join_dependency|
|
1116
|
-
join_dependency.each
|
1117
|
-
yield join
|
1118
|
-
end
|
1301
|
+
join_dependency.each(&block)
|
1119
1302
|
end
|
1120
1303
|
end
|
1121
1304
|
|
@@ -1157,14 +1340,6 @@ module ActiveRecord
|
|
1157
1340
|
unless annotate_values.empty?
|
1158
1341
|
annotates = annotate_values
|
1159
1342
|
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
1343
|
arel.comment(*annotates)
|
1169
1344
|
end
|
1170
1345
|
|
@@ -1172,8 +1347,7 @@ module ActiveRecord
|
|
1172
1347
|
end
|
1173
1348
|
|
1174
1349
|
def build_cast_value(name, value)
|
1175
|
-
|
1176
|
-
Arel::Nodes::BindParam.new(cast_value)
|
1350
|
+
ActiveModel::Attribute.with_cast_value(name, value, Type.default_value)
|
1177
1351
|
end
|
1178
1352
|
|
1179
1353
|
def build_from
|
@@ -1284,7 +1458,7 @@ module ActiveRecord
|
|
1284
1458
|
def build_select(arel)
|
1285
1459
|
if select_values.any?
|
1286
1460
|
arel.project(*arel_columns(select_values))
|
1287
|
-
elsif klass.ignored_columns.any?
|
1461
|
+
elsif klass.ignored_columns.any? || klass.enumerate_columns_in_select_statements
|
1288
1462
|
arel.project(*klass.column_names.map { |field| table[field] })
|
1289
1463
|
else
|
1290
1464
|
arel.project(table[Arel.star])
|
@@ -1425,12 +1599,17 @@ module ActiveRecord
|
|
1425
1599
|
order_args.map! do |arg|
|
1426
1600
|
klass.sanitize_sql_for_order(arg)
|
1427
1601
|
end
|
1428
|
-
order_args.flatten!
|
1429
|
-
order_args.compact_blank!
|
1430
1602
|
end
|
1431
1603
|
|
1432
1604
|
def column_references(order_args)
|
1433
|
-
references = order_args.
|
1605
|
+
references = order_args.flat_map do |arg|
|
1606
|
+
case arg
|
1607
|
+
when String, Symbol
|
1608
|
+
arg
|
1609
|
+
when Hash
|
1610
|
+
arg.keys
|
1611
|
+
end
|
1612
|
+
end
|
1434
1613
|
references.map! { |arg| arg =~ /^\W?(\w+)\W?\./ && $1 }.compact!
|
1435
1614
|
references
|
1436
1615
|
end
|
@@ -1478,19 +1657,19 @@ module ActiveRecord
|
|
1478
1657
|
# Post.references() # raises an error
|
1479
1658
|
# Post.references([]) # does not raise an error
|
1480
1659
|
#
|
1481
|
-
# This particular method should be called with a method_name and the args
|
1660
|
+
# This particular method should be called with a method_name (__callee__) and the args
|
1482
1661
|
# passed into that method as an input. For example:
|
1483
1662
|
#
|
1484
1663
|
# def references(*args)
|
1485
|
-
# check_if_method_has_arguments!(
|
1664
|
+
# check_if_method_has_arguments!(__callee__, args)
|
1486
1665
|
# ...
|
1487
1666
|
# end
|
1488
1667
|
def check_if_method_has_arguments!(method_name, args, message = nil)
|
1489
1668
|
if args.blank?
|
1490
1669
|
raise ArgumentError, message || "The method .#{method_name}() must contain arguments."
|
1491
|
-
elsif block_given?
|
1492
|
-
yield args
|
1493
1670
|
else
|
1671
|
+
yield args if block_given?
|
1672
|
+
|
1494
1673
|
args.flatten!
|
1495
1674
|
args.compact_blank!
|
1496
1675
|
end
|
@@ -1514,11 +1693,4 @@ module ActiveRecord
|
|
1514
1693
|
end
|
1515
1694
|
end
|
1516
1695
|
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
1696
|
end
|