activerecord 5.2.3 → 6.0.0.rc2
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 +605 -554
- data/MIT-LICENSE +3 -1
- data/README.rdoc +4 -2
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +9 -2
- data/lib/active_record/aggregations.rb +4 -2
- data/lib/active_record/associations.rb +19 -14
- data/lib/active_record/associations/association.rb +52 -19
- data/lib/active_record/associations/association_scope.rb +4 -6
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +5 -15
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +6 -21
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -10
- data/lib/active_record/associations/has_many_through_association.rb +18 -25
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +24 -28
- data/lib/active_record/associations/join_dependency/join_association.rb +27 -7
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/preloader.rb +39 -31
- data/lib/active_record/associations/preloader/association.rb +38 -36
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/attribute_assignment.rb +7 -10
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -22
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -53
- data/lib/active_record/attribute_methods/serialization.rb +1 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_methods/write.rb +17 -24
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +15 -5
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +5 -19
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +111 -19
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +95 -123
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +20 -11
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
- data/lib/active_record/connection_adapters/abstract_adapter.rb +172 -41
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +128 -194
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +73 -13
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +24 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +160 -74
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +127 -143
- data/lib/active_record/connection_handling.rb +149 -27
- data/lib/active_record/core.rb +100 -60
- data/lib/active_record/counter_cache.rb +4 -29
- data/lib/active_record/database_configurations.rb +204 -0
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +79 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +28 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +140 -472
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +13 -3
- data/lib/active_record/insert_all.rb +180 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +10 -2
- data/lib/active_record/locking/optimistic.rb +5 -6
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +7 -26
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +90 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +87 -76
- data/lib/active_record/migration/command_recorder.rb +50 -6
- data/lib/active_record/migration/compatibility.rb +76 -49
- data/lib/active_record/model_schema.rb +30 -9
- data/lib/active_record/nested_attributes.rb +2 -2
- data/lib/active_record/no_touching.rb +7 -0
- data/lib/active_record/persistence.rb +228 -24
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +32 -20
- data/lib/active_record/railtie.rb +80 -43
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +193 -46
- data/lib/active_record/reflection.rb +42 -44
- data/lib/active_record/relation.rb +310 -80
- data/lib/active_record/relation/batches.rb +13 -10
- data/lib/active_record/relation/calculations.rb +58 -49
- data/lib/active_record/relation/delegation.rb +26 -43
- data/lib/active_record/relation/finder_methods.rb +14 -27
- data/lib/active_record/relation/merger.rb +11 -20
- data/lib/active_record/relation/predicate_builder.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +182 -68
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +14 -10
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/result.rb +30 -11
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +5 -1
- data/lib/active_record/scoping.rb +8 -8
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +19 -15
- data/lib/active_record/statement_cache.rb +32 -5
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/table_metadata.rb +10 -17
- data/lib/active_record/tasks/database_tasks.rb +159 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
- data/lib/active_record/test_databases.rb +38 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +39 -25
- data/lib/active_record/touch_later.rb +4 -2
- data/lib/active_record/transactions.rb +56 -65
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type.rb +3 -4
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/arel.rb +51 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/visitors/depth_first.rb +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record/migration.rb +14 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +109 -27
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -117,18 +117,16 @@ module ActiveRecord
|
|
117
117
|
if other.klass == relation.klass
|
118
118
|
relation.joins!(*other.joins_values)
|
119
119
|
else
|
120
|
-
|
120
|
+
associations, others = other.joins_values.partition do |join|
|
121
121
|
case join
|
122
|
-
when Hash, Symbol, Array
|
123
|
-
ActiveRecord::Associations::JoinDependency.new(
|
124
|
-
other.klass, other.table, join
|
125
|
-
)
|
126
|
-
else
|
127
|
-
join
|
122
|
+
when Hash, Symbol, Array; true
|
128
123
|
end
|
129
124
|
end
|
130
125
|
|
131
|
-
|
126
|
+
join_dependency = other.construct_join_dependency(
|
127
|
+
associations, Arel::Nodes::InnerJoin
|
128
|
+
)
|
129
|
+
relation.joins!(join_dependency, *others)
|
132
130
|
end
|
133
131
|
end
|
134
132
|
|
@@ -138,18 +136,11 @@ module ActiveRecord
|
|
138
136
|
if other.klass == relation.klass
|
139
137
|
relation.left_outer_joins!(*other.left_outer_joins_values)
|
140
138
|
else
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
)
|
147
|
-
else
|
148
|
-
join
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
relation.left_outer_joins!(*joins_dependency)
|
139
|
+
associations = other.left_outer_joins_values
|
140
|
+
join_dependency = other.construct_join_dependency(
|
141
|
+
associations, Arel::Nodes::OuterJoin
|
142
|
+
)
|
143
|
+
relation.joins!(join_dependency)
|
153
144
|
end
|
154
145
|
end
|
155
146
|
|
@@ -27,7 +27,7 @@ module ActiveRecord
|
|
27
27
|
key
|
28
28
|
else
|
29
29
|
key = key.to_s
|
30
|
-
key.split("."
|
30
|
+
key.split(".").first if key.include?(".")
|
31
31
|
end
|
32
32
|
end.compact
|
33
33
|
end
|
@@ -62,9 +62,6 @@ module ActiveRecord
|
|
62
62
|
end
|
63
63
|
|
64
64
|
protected
|
65
|
-
|
66
|
-
attr_reader :table
|
67
|
-
|
68
65
|
def expand_from_hash(attributes)
|
69
66
|
return ["1=0"] if attributes.empty?
|
70
67
|
|
@@ -115,6 +112,7 @@ module ActiveRecord
|
|
115
112
|
end
|
116
113
|
|
117
114
|
private
|
115
|
+
attr_reader :table
|
118
116
|
|
119
117
|
def associated_predicate_builder(association_name)
|
120
118
|
self.class.new(table.associated_table(association_name))
|
@@ -122,11 +120,11 @@ module ActiveRecord
|
|
122
120
|
|
123
121
|
def convert_dot_notation_to_hash(attributes)
|
124
122
|
dot_notation = attributes.select do |k, v|
|
125
|
-
k.include?("."
|
123
|
+
k.include?(".") && !v.is_a?(Hash)
|
126
124
|
end
|
127
125
|
|
128
126
|
dot_notation.each_key do |key|
|
129
|
-
table_name, column_name = key.split("."
|
127
|
+
table_name, column_name = key.split(".")
|
130
128
|
value = attributes.delete(key)
|
131
129
|
attributes[table_name] ||= {}
|
132
130
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/array/extract"
|
4
|
+
|
3
5
|
module ActiveRecord
|
4
6
|
class PredicateBuilder
|
5
7
|
class ArrayHandler # :nodoc:
|
@@ -11,8 +13,8 @@ module ActiveRecord
|
|
11
13
|
return attribute.in([]) if value.empty?
|
12
14
|
|
13
15
|
values = value.map { |x| x.is_a?(Base) ? x.id : x }
|
14
|
-
nils
|
15
|
-
ranges
|
16
|
+
nils = values.extract!(&:nil?)
|
17
|
+
ranges = values.extract! { |v| v.is_a?(Range) }
|
16
18
|
|
17
19
|
values_predicate =
|
18
20
|
case values.length
|
@@ -34,8 +36,7 @@ module ActiveRecord
|
|
34
36
|
array_predicates.inject(&:or)
|
35
37
|
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
+
private
|
39
40
|
attr_reader :predicate_builder
|
40
41
|
|
41
42
|
module NullPredicate # :nodoc:
|
@@ -12,12 +12,9 @@ module ActiveRecord
|
|
12
12
|
[associated_table.association_join_foreign_key.to_s => ids]
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
17
|
-
protected
|
15
|
+
private
|
18
16
|
attr_reader :associated_table, :value
|
19
17
|
|
20
|
-
private
|
21
18
|
def ids
|
22
19
|
case value
|
23
20
|
when Relation
|
@@ -17,12 +17,9 @@ module ActiveRecord
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
22
|
-
protected
|
20
|
+
private
|
23
21
|
attr_reader :associated_table, :values
|
24
22
|
|
25
|
-
private
|
26
23
|
def type_to_ids_mapping
|
27
24
|
default_hash = Hash.new { |hsh, key| hsh[key] = [] }
|
28
25
|
values.each_with_object(default_hash) do |value, hash|
|
@@ -3,11 +3,7 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
class PredicateBuilder
|
5
5
|
class RangeHandler # :nodoc:
|
6
|
-
|
7
|
-
def exclude_end?
|
8
|
-
false
|
9
|
-
end
|
10
|
-
end
|
6
|
+
RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
|
11
7
|
|
12
8
|
def initialize(predicate_builder)
|
13
9
|
@predicate_builder = predicate_builder
|
@@ -16,26 +12,10 @@ module ActiveRecord
|
|
16
12
|
def call(attribute, value)
|
17
13
|
begin_bind = predicate_builder.build_bind_attribute(attribute.name, value.begin)
|
18
14
|
end_bind = predicate_builder.build_bind_attribute(attribute.name, value.end)
|
19
|
-
|
20
|
-
if begin_bind.value.infinity?
|
21
|
-
if end_bind.value.infinity?
|
22
|
-
attribute.not_in([])
|
23
|
-
elsif value.exclude_end?
|
24
|
-
attribute.lt(end_bind)
|
25
|
-
else
|
26
|
-
attribute.lteq(end_bind)
|
27
|
-
end
|
28
|
-
elsif end_bind.value.infinity?
|
29
|
-
attribute.gteq(begin_bind)
|
30
|
-
elsif value.exclude_end?
|
31
|
-
attribute.gteq(begin_bind).and(attribute.lt(end_bind))
|
32
|
-
else
|
33
|
-
attribute.between(RangeWithBinds.new(begin_bind, end_bind))
|
34
|
-
end
|
15
|
+
attribute.between(RangeWithBinds.new(begin_bind, end_bind, value.exclude_end?))
|
35
16
|
end
|
36
17
|
|
37
|
-
|
38
|
-
|
18
|
+
private
|
39
19
|
attr_reader :predicate_builder
|
40
20
|
end
|
41
21
|
end
|
@@ -22,22 +22,27 @@ module ActiveRecord
|
|
22
22
|
value_before_type_cast.nil? ||
|
23
23
|
type.respond_to?(:subtype, true) && value_for_database.nil?
|
24
24
|
end
|
25
|
+
rescue ::RangeError
|
25
26
|
end
|
26
27
|
|
27
|
-
def
|
28
|
-
|
29
|
-
value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
|
30
|
-
@_boundable = true
|
28
|
+
def infinite?
|
29
|
+
infinity?(value_before_type_cast) || infinity?(value_for_database)
|
31
30
|
rescue ::RangeError
|
32
|
-
@_boundable = false
|
33
31
|
end
|
34
32
|
|
35
|
-
def
|
36
|
-
|
33
|
+
def unboundable?
|
34
|
+
if defined?(@_unboundable)
|
35
|
+
@_unboundable
|
36
|
+
else
|
37
|
+
value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
|
38
|
+
@_unboundable = nil
|
39
|
+
end
|
40
|
+
rescue ::RangeError
|
41
|
+
@_unboundable = type.cast(value_before_type_cast) <=> 0
|
37
42
|
end
|
38
43
|
|
39
44
|
private
|
40
|
-
def
|
45
|
+
def infinity?(value)
|
41
46
|
value.respond_to?(:infinite?) && value.infinite?
|
42
47
|
end
|
43
48
|
end
|
@@ -41,18 +41,31 @@ module ActiveRecord
|
|
41
41
|
#
|
42
42
|
# User.where.not(name: %w(Ko1 Nobu))
|
43
43
|
# # SELECT * FROM users WHERE name NOT IN ('Ko1', 'Nobu')
|
44
|
-
#
|
45
|
-
# User.where.not(name: "Jon", role: "admin")
|
46
|
-
# # SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
|
47
44
|
def not(opts, *rest)
|
48
45
|
opts = sanitize_forbidden_attributes(opts)
|
49
46
|
|
50
47
|
where_clause = @scope.send(:where_clause_factory).build(opts, rest)
|
51
48
|
|
52
49
|
@scope.references!(PredicateBuilder.references(opts)) if Hash === opts
|
53
|
-
|
50
|
+
|
51
|
+
if not_behaves_as_nor?(opts)
|
52
|
+
ActiveSupport::Deprecation.warn(<<~MSG.squish)
|
53
|
+
NOT conditions will no longer behave as NOR in Rails 6.1.
|
54
|
+
To continue using NOR conditions, NOT each conditions manually
|
55
|
+
(`#{ opts.keys.map { |key| ".where.not(#{key.inspect} => ...)" }.join }`).
|
56
|
+
MSG
|
57
|
+
@scope.where_clause += where_clause.invert(:nor)
|
58
|
+
else
|
59
|
+
@scope.where_clause += where_clause.invert
|
60
|
+
end
|
61
|
+
|
54
62
|
@scope
|
55
63
|
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def not_behaves_as_nor?(opts)
|
67
|
+
opts.is_a?(Hash) && opts.size > 1
|
68
|
+
end
|
56
69
|
end
|
57
70
|
|
58
71
|
FROZEN_EMPTY_ARRAY = [].freeze
|
@@ -67,11 +80,13 @@ module ActiveRecord
|
|
67
80
|
end
|
68
81
|
class_eval <<-CODE, __FILE__, __LINE__ + 1
|
69
82
|
def #{method_name} # def includes_values
|
70
|
-
|
83
|
+
default = DEFAULT_VALUES[:#{name}] # default = DEFAULT_VALUES[:includes]
|
84
|
+
@values.fetch(:#{name}, default) # @values.fetch(:includes, default)
|
71
85
|
end # end
|
72
86
|
|
73
87
|
def #{method_name}=(value) # def includes_values=(value)
|
74
|
-
|
88
|
+
assert_mutability! # assert_mutability!
|
89
|
+
@values[:#{name}] = value # @values[:includes] = value
|
75
90
|
end # end
|
76
91
|
CODE
|
77
92
|
end
|
@@ -100,7 +115,7 @@ module ActiveRecord
|
|
100
115
|
#
|
101
116
|
# === conditions
|
102
117
|
#
|
103
|
-
# If you want to add conditions to your included models you'll have
|
118
|
+
# If you want to add string conditions to your included models, you'll have
|
104
119
|
# to explicitly reference them. For example:
|
105
120
|
#
|
106
121
|
# User.includes(:posts).where('posts.name = ?', 'example')
|
@@ -111,6 +126,12 @@ module ActiveRecord
|
|
111
126
|
#
|
112
127
|
# Note that #includes works with association names while #references needs
|
113
128
|
# the actual table name.
|
129
|
+
#
|
130
|
+
# If you pass the conditions via hash, you don't need to call #references
|
131
|
+
# explicitly, as #where references the tables for you. For example, this
|
132
|
+
# will work correctly:
|
133
|
+
#
|
134
|
+
# User.includes(:posts).where(posts: { name: 'example' })
|
114
135
|
def includes(*args)
|
115
136
|
check_if_method_has_arguments!(:includes, args)
|
116
137
|
spawn.includes!(*args)
|
@@ -154,6 +175,19 @@ module ActiveRecord
|
|
154
175
|
self
|
155
176
|
end
|
156
177
|
|
178
|
+
# Extracts a named +association+ from the relation. The named association is first preloaded,
|
179
|
+
# then the individual association records are collected from the relation. Like so:
|
180
|
+
#
|
181
|
+
# account.memberships.extract_associated(:user)
|
182
|
+
# # => Returns collection of User records
|
183
|
+
#
|
184
|
+
# This is short-hand for:
|
185
|
+
#
|
186
|
+
# account.memberships.preload(:user).collect(&:user)
|
187
|
+
def extract_associated(association)
|
188
|
+
preload(association).collect(&association)
|
189
|
+
end
|
190
|
+
|
157
191
|
# Use to indicate that the given +table_names+ are referenced by an SQL string,
|
158
192
|
# and should therefore be JOINed in any query rather than loaded separately.
|
159
193
|
# This method only works in conjunction with #includes.
|
@@ -231,14 +265,33 @@ module ActiveRecord
|
|
231
265
|
end
|
232
266
|
|
233
267
|
def _select!(*fields) # :nodoc:
|
268
|
+
fields.reject!(&:blank?)
|
234
269
|
fields.flatten!
|
235
|
-
fields.map! do |field|
|
236
|
-
klass.attribute_alias?(field) ? klass.attribute_alias(field).to_sym : field
|
237
|
-
end
|
238
270
|
self.select_values += fields
|
239
271
|
self
|
240
272
|
end
|
241
273
|
|
274
|
+
# Allows you to change a previously set select statement.
|
275
|
+
#
|
276
|
+
# Post.select(:title, :body)
|
277
|
+
# # SELECT `posts`.`title`, `posts`.`body` FROM `posts`
|
278
|
+
#
|
279
|
+
# Post.select(:title, :body).reselect(:created_at)
|
280
|
+
# # SELECT `posts`.`created_at` FROM `posts`
|
281
|
+
#
|
282
|
+
# This is short-hand for <tt>unscope(:select).select(fields)</tt>.
|
283
|
+
# Note that we're unscoping the entire select statement.
|
284
|
+
def reselect(*args)
|
285
|
+
check_if_method_has_arguments!(:reselect, args)
|
286
|
+
spawn.reselect!(*args)
|
287
|
+
end
|
288
|
+
|
289
|
+
# Same as #reselect but operates on relation in-place instead of copying.
|
290
|
+
def reselect!(*args) # :nodoc:
|
291
|
+
self.select_values = args
|
292
|
+
self
|
293
|
+
end
|
294
|
+
|
242
295
|
# Allows to specify a group attribute:
|
243
296
|
#
|
244
297
|
# User.group(:name)
|
@@ -327,8 +380,8 @@ module ActiveRecord
|
|
327
380
|
end
|
328
381
|
|
329
382
|
VALID_UNSCOPING_VALUES = Set.new([:where, :select, :group, :order, :lock,
|
330
|
-
:limit, :offset, :joins, :left_outer_joins,
|
331
|
-
:includes, :from, :readonly, :having])
|
383
|
+
:limit, :offset, :joins, :left_outer_joins, :annotate,
|
384
|
+
:includes, :from, :readonly, :having, :optimizer_hints])
|
332
385
|
|
333
386
|
# Removes an unwanted relation that is already defined on a chain of relations.
|
334
387
|
# This is useful when passing around chains of relations and would like to
|
@@ -379,7 +432,8 @@ module ActiveRecord
|
|
379
432
|
if !VALID_UNSCOPING_VALUES.include?(scope)
|
380
433
|
raise ArgumentError, "Called unscope() with invalid unscoping argument ':#{scope}'. Valid arguments are :#{VALID_UNSCOPING_VALUES.to_a.join(", :")}."
|
381
434
|
end
|
382
|
-
|
435
|
+
assert_mutability!
|
436
|
+
@values[scope] = DEFAULT_VALUES[scope]
|
383
437
|
when Hash
|
384
438
|
scope.each do |key, target_value|
|
385
439
|
if key != :where
|
@@ -879,6 +933,29 @@ module ActiveRecord
|
|
879
933
|
self
|
880
934
|
end
|
881
935
|
|
936
|
+
# Specify optimizer hints to be used in the SELECT statement.
|
937
|
+
#
|
938
|
+
# Example (for MySQL):
|
939
|
+
#
|
940
|
+
# Topic.optimizer_hints("MAX_EXECUTION_TIME(50000)", "NO_INDEX_MERGE(topics)")
|
941
|
+
# # SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
|
942
|
+
#
|
943
|
+
# Example (for PostgreSQL with pg_hint_plan):
|
944
|
+
#
|
945
|
+
# Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
|
946
|
+
# # SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
|
947
|
+
def optimizer_hints(*args)
|
948
|
+
check_if_method_has_arguments!(:optimizer_hints, args)
|
949
|
+
spawn.optimizer_hints!(*args)
|
950
|
+
end
|
951
|
+
|
952
|
+
def optimizer_hints!(*args) # :nodoc:
|
953
|
+
args.flatten!
|
954
|
+
|
955
|
+
self.optimizer_hints_values |= args
|
956
|
+
self
|
957
|
+
end
|
958
|
+
|
882
959
|
# Reverse the existing order clause on the relation.
|
883
960
|
#
|
884
961
|
# User.order('name ASC').reverse_order # generated SQL has 'ORDER BY name DESC'
|
@@ -898,26 +975,52 @@ module ActiveRecord
|
|
898
975
|
self
|
899
976
|
end
|
900
977
|
|
978
|
+
def skip_preloading! # :nodoc:
|
979
|
+
self.skip_preloading_value = true
|
980
|
+
self
|
981
|
+
end
|
982
|
+
|
983
|
+
# Adds an SQL comment to queries generated from this relation. For example:
|
984
|
+
#
|
985
|
+
# User.annotate("selecting user names").select(:name)
|
986
|
+
# # SELECT "users"."name" FROM "users" /* selecting user names */
|
987
|
+
#
|
988
|
+
# User.annotate("selecting", "user", "names").select(:name)
|
989
|
+
# # SELECT "users"."name" FROM "users" /* selecting */ /* user */ /* names */
|
990
|
+
#
|
991
|
+
# The SQL block comment delimiters, "/*" and "*/", will be added automatically.
|
992
|
+
def annotate(*args)
|
993
|
+
check_if_method_has_arguments!(:annotate, args)
|
994
|
+
spawn.annotate!(*args)
|
995
|
+
end
|
996
|
+
|
997
|
+
# Like #annotate, but modifies relation in place.
|
998
|
+
def annotate!(*args) # :nodoc:
|
999
|
+
self.annotate_values += args
|
1000
|
+
self
|
1001
|
+
end
|
1002
|
+
|
901
1003
|
# Returns the Arel object associated with the relation.
|
902
1004
|
def arel(aliases = nil) # :nodoc:
|
903
1005
|
@arel ||= build_arel(aliases)
|
904
1006
|
end
|
905
1007
|
|
906
|
-
|
907
|
-
|
908
|
-
|
1008
|
+
def construct_join_dependency(associations, join_type) # :nodoc:
|
1009
|
+
ActiveRecord::Associations::JoinDependency.new(
|
1010
|
+
klass, table, associations, join_type
|
1011
|
+
)
|
909
1012
|
end
|
910
1013
|
|
911
1014
|
protected
|
1015
|
+
def build_subquery(subquery_alias, select_value) # :nodoc:
|
1016
|
+
subquery = except(:optimizer_hints).arel.as(subquery_alias)
|
912
1017
|
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
@values[name] = value
|
1018
|
+
Arel::SelectManager.new(subquery).project(select_value).tap do |arel|
|
1019
|
+
arel.optimizer_hints(*optimizer_hints_values) unless optimizer_hints_values.empty?
|
1020
|
+
end
|
917
1021
|
end
|
918
1022
|
|
919
1023
|
private
|
920
|
-
|
921
1024
|
def assert_mutability!
|
922
1025
|
raise ImmutableRelation if @loaded
|
923
1026
|
raise ImmutableRelation if defined?(@arel) && @arel
|
@@ -926,14 +1029,17 @@ module ActiveRecord
|
|
926
1029
|
def build_arel(aliases)
|
927
1030
|
arel = Arel::SelectManager.new(table)
|
928
1031
|
|
929
|
-
|
930
|
-
|
1032
|
+
if !joins_values.empty?
|
1033
|
+
build_joins(arel, joins_values.flatten, aliases)
|
1034
|
+
elsif !left_outer_joins_values.empty?
|
1035
|
+
build_left_outer_joins(arel, left_outer_joins_values.flatten, aliases)
|
1036
|
+
end
|
931
1037
|
|
932
1038
|
arel.where(where_clause.ast) unless where_clause.empty?
|
933
1039
|
arel.having(having_clause.ast) unless having_clause.empty?
|
934
1040
|
if limit_value
|
935
1041
|
limit_attribute = ActiveModel::Attribute.with_cast_value(
|
936
|
-
"LIMIT"
|
1042
|
+
"LIMIT",
|
937
1043
|
connection.sanitize_limit(limit_value),
|
938
1044
|
Type.default_value,
|
939
1045
|
)
|
@@ -941,7 +1047,7 @@ module ActiveRecord
|
|
941
1047
|
end
|
942
1048
|
if offset_value
|
943
1049
|
offset_attribute = ActiveModel::Attribute.with_cast_value(
|
944
|
-
"OFFSET"
|
1050
|
+
"OFFSET",
|
945
1051
|
offset_value.to_i,
|
946
1052
|
Type.default_value,
|
947
1053
|
)
|
@@ -953,9 +1059,11 @@ module ActiveRecord
|
|
953
1059
|
|
954
1060
|
build_select(arel)
|
955
1061
|
|
1062
|
+
arel.optimizer_hints(*optimizer_hints_values) unless optimizer_hints_values.empty?
|
956
1063
|
arel.distinct(distinct_value)
|
957
1064
|
arel.from(build_from) unless from_clause.empty?
|
958
1065
|
arel.lock(lock_value) if lock_value
|
1066
|
+
arel.comment(*annotate_values) unless annotate_values.empty?
|
959
1067
|
|
960
1068
|
arel
|
961
1069
|
end
|
@@ -975,22 +1083,28 @@ module ActiveRecord
|
|
975
1083
|
end
|
976
1084
|
end
|
977
1085
|
|
978
|
-
def
|
979
|
-
|
980
|
-
case
|
1086
|
+
def valid_association_list(associations)
|
1087
|
+
associations.each do |association|
|
1088
|
+
case association
|
981
1089
|
when Hash, Symbol, Array
|
982
|
-
|
983
|
-
when ActiveRecord::Associations::JoinDependency
|
984
|
-
:stashed_join
|
1090
|
+
# valid
|
985
1091
|
else
|
986
1092
|
raise ArgumentError, "only Hash, Symbol and Array are allowed"
|
987
1093
|
end
|
988
1094
|
end
|
1095
|
+
end
|
989
1096
|
|
1097
|
+
def build_left_outer_joins(manager, outer_joins, aliases)
|
1098
|
+
buckets = { association_join: valid_association_list(outer_joins) }
|
990
1099
|
build_join_query(manager, buckets, Arel::Nodes::OuterJoin, aliases)
|
991
1100
|
end
|
992
1101
|
|
993
1102
|
def build_joins(manager, joins, aliases)
|
1103
|
+
unless left_outer_joins_values.empty?
|
1104
|
+
left_joins = valid_association_list(left_outer_joins_values.flatten)
|
1105
|
+
joins.unshift construct_join_dependency(left_joins, Arel::Nodes::OuterJoin)
|
1106
|
+
end
|
1107
|
+
|
994
1108
|
buckets = joins.group_by do |join|
|
995
1109
|
case join
|
996
1110
|
when String
|
@@ -1014,29 +1128,21 @@ module ActiveRecord
|
|
1014
1128
|
|
1015
1129
|
association_joins = buckets[:association_join]
|
1016
1130
|
stashed_joins = buckets[:stashed_join]
|
1017
|
-
join_nodes = buckets[:join_node].uniq
|
1018
|
-
string_joins = buckets[:string_join].map(&:strip).uniq
|
1019
|
-
|
1020
|
-
join_list = join_nodes + convert_join_strings_to_ast(string_joins)
|
1021
|
-
alias_tracker = alias_tracker(join_list, aliases)
|
1022
|
-
|
1023
|
-
join_dependency = ActiveRecord::Associations::JoinDependency.new(
|
1024
|
-
klass, table, association_joins
|
1025
|
-
)
|
1131
|
+
join_nodes = buckets[:join_node].tap(&:uniq!)
|
1132
|
+
string_joins = buckets[:string_join].delete_if(&:blank?).map!(&:strip).tap(&:uniq!)
|
1026
1133
|
|
1027
|
-
|
1028
|
-
joins.each { |join| manager.from(join) }
|
1134
|
+
string_joins.map! { |join| table.create_string_join(Arel.sql(join)) }
|
1029
1135
|
|
1030
|
-
manager.join_sources
|
1136
|
+
join_sources = manager.join_sources
|
1137
|
+
join_sources.concat(join_nodes) unless join_nodes.empty?
|
1031
1138
|
|
1032
|
-
|
1033
|
-
|
1139
|
+
unless association_joins.empty? && stashed_joins.empty?
|
1140
|
+
alias_tracker = alias_tracker(join_nodes + string_joins, aliases)
|
1141
|
+
join_dependency = construct_join_dependency(association_joins, join_type)
|
1142
|
+
join_sources.concat(join_dependency.join_constraints(stashed_joins, alias_tracker))
|
1143
|
+
end
|
1034
1144
|
|
1035
|
-
|
1036
|
-
joins
|
1037
|
-
.flatten
|
1038
|
-
.reject(&:blank?)
|
1039
|
-
.map { |join| table.create_string_join(Arel.sql(join)) }
|
1145
|
+
join_sources.concat(string_joins) unless string_joins.empty?
|
1040
1146
|
end
|
1041
1147
|
|
1042
1148
|
def build_select(arel)
|
@@ -1053,10 +1159,11 @@ module ActiveRecord
|
|
1053
1159
|
columns.flat_map do |field|
|
1054
1160
|
case field
|
1055
1161
|
when Symbol
|
1056
|
-
field
|
1057
|
-
|
1162
|
+
arel_column(field.to_s) do |attr_name|
|
1163
|
+
connection.quote_table_name(attr_name)
|
1164
|
+
end
|
1058
1165
|
when String
|
1059
|
-
arel_column(field)
|
1166
|
+
arel_column(field, &:itself)
|
1060
1167
|
when Proc
|
1061
1168
|
field.call
|
1062
1169
|
else
|
@@ -1066,13 +1173,13 @@ module ActiveRecord
|
|
1066
1173
|
end
|
1067
1174
|
|
1068
1175
|
def arel_column(field)
|
1069
|
-
field = klass.
|
1176
|
+
field = klass.attribute_aliases[field] || field
|
1070
1177
|
from = from_clause.name || from_clause.value
|
1071
1178
|
|
1072
1179
|
if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
|
1073
1180
|
arel_attribute(field)
|
1074
1181
|
else
|
1075
|
-
yield
|
1182
|
+
yield field
|
1076
1183
|
end
|
1077
1184
|
end
|
1078
1185
|
|
@@ -1095,7 +1202,7 @@ module ActiveRecord
|
|
1095
1202
|
o.reverse
|
1096
1203
|
when String
|
1097
1204
|
if does_not_support_reverse?(o)
|
1098
|
-
raise IrreversibleOrderError, "Order #{o.inspect}
|
1205
|
+
raise IrreversibleOrderError, "Order #{o.inspect} cannot be reversed automatically"
|
1099
1206
|
end
|
1100
1207
|
o.split(",").map! do |s|
|
1101
1208
|
s.strip!
|
@@ -1115,7 +1222,7 @@ module ActiveRecord
|
|
1115
1222
|
# Uses SQL function with multiple arguments.
|
1116
1223
|
(order.include?(",") && order.split(",").find { |section| section.count("(") != section.count(")") }) ||
|
1117
1224
|
# Uses "nulls first" like construction.
|
1118
|
-
|
1225
|
+
/\bnulls\s+(?:first|last)\b/i.match?(order)
|
1119
1226
|
end
|
1120
1227
|
|
1121
1228
|
def build_order(arel)
|
@@ -1141,14 +1248,15 @@ module ActiveRecord
|
|
1141
1248
|
end
|
1142
1249
|
|
1143
1250
|
def preprocess_order_args(order_args)
|
1251
|
+
order_args.reject!(&:blank?)
|
1144
1252
|
order_args.map! do |arg|
|
1145
1253
|
klass.sanitize_sql_for_order(arg)
|
1146
1254
|
end
|
1147
1255
|
order_args.flatten!
|
1148
1256
|
|
1149
|
-
@klass.
|
1257
|
+
@klass.disallow_raw_sql!(
|
1150
1258
|
order_args.flat_map { |a| a.is_a?(Hash) ? a.keys : a },
|
1151
|
-
|
1259
|
+
permit: connection.column_name_with_order_matcher
|
1152
1260
|
)
|
1153
1261
|
|
1154
1262
|
validate_order_args(order_args)
|
@@ -1161,20 +1269,14 @@ module ActiveRecord
|
|
1161
1269
|
order_args.map! do |arg|
|
1162
1270
|
case arg
|
1163
1271
|
when Symbol
|
1164
|
-
arg
|
1165
|
-
arel_column(arg) {
|
1166
|
-
Arel.sql(connection.quote_table_name(arg))
|
1167
|
-
}.asc
|
1272
|
+
order_column(arg.to_s).asc
|
1168
1273
|
when Hash
|
1169
1274
|
arg.map { |field, dir|
|
1170
1275
|
case field
|
1171
1276
|
when Arel::Nodes::SqlLiteral
|
1172
1277
|
field.send(dir.downcase)
|
1173
1278
|
else
|
1174
|
-
field
|
1175
|
-
arel_column(field) {
|
1176
|
-
Arel.sql(connection.quote_table_name(field))
|
1177
|
-
}.send(dir.downcase)
|
1279
|
+
order_column(field.to_s).send(dir.downcase)
|
1178
1280
|
end
|
1179
1281
|
}
|
1180
1282
|
else
|
@@ -1183,6 +1285,16 @@ module ActiveRecord
|
|
1183
1285
|
end.flatten!
|
1184
1286
|
end
|
1185
1287
|
|
1288
|
+
def order_column(field)
|
1289
|
+
arel_column(field) do |attr_name|
|
1290
|
+
if attr_name == "count" && !group_values.empty?
|
1291
|
+
arel_attribute(attr_name)
|
1292
|
+
else
|
1293
|
+
Arel.sql(connection.quote_table_name(attr_name))
|
1294
|
+
end
|
1295
|
+
end
|
1296
|
+
end
|
1297
|
+
|
1186
1298
|
# Checks to make sure that the arguments are not blank. Note that if some
|
1187
1299
|
# blank-like object were initially passed into the query method, then this
|
1188
1300
|
# method will not raise an error.
|
@@ -1207,8 +1319,10 @@ module ActiveRecord
|
|
1207
1319
|
|
1208
1320
|
STRUCTURAL_OR_METHODS = Relation::VALUE_METHODS - [:extending, :where, :having, :unscope, :references]
|
1209
1321
|
def structurally_incompatible_values_for_or(other)
|
1322
|
+
values = other.values
|
1210
1323
|
STRUCTURAL_OR_METHODS.reject do |method|
|
1211
|
-
|
1324
|
+
default = DEFAULT_VALUES[method]
|
1325
|
+
@values.fetch(method, default) == values.fetch(method, default)
|
1212
1326
|
end
|
1213
1327
|
end
|
1214
1328
|
|