activerecord 5.2.6 → 6.0.5
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 +928 -559
- data/MIT-LICENSE +3 -1
- data/README.rdoc +5 -3
- data/examples/performance.rb +1 -1
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +4 -3
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +55 -19
- data/lib/active_record/associations/association_scope.rb +11 -7
- 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 +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
- 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 +19 -23
- data/lib/active_record/associations/collection_proxy.rb +14 -17
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -11
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- 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/join_association.rb +16 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +4 -4
- data/lib/active_record/associations/join_dependency.rb +47 -30
- data/lib/active_record/associations/preloader/association.rb +61 -41
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/preloader.rb +44 -33
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +21 -16
- data/lib/active_record/attribute_assignment.rb +7 -11
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -24
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -54
- data/lib/active_record/attribute_methods/serialization.rb +1 -2
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
- data/lib/active_record/attribute_methods/write.rb +17 -25
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attributes.rb +13 -1
- data/lib/active_record/autosave_association.rb +12 -14
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +6 -21
- data/lib/active_record/coders/yaml_column.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -18
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +105 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
- data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -217
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
- 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 +139 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.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 +5 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
- 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 +119 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +137 -147
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +139 -26
- data/lib/active_record/core.rb +107 -66
- data/lib/active_record/counter_cache.rb +8 -30
- 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 +78 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +44 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -2
- 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 +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +144 -474
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +13 -6
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +11 -3
- data/lib/active_record/locking/optimistic.rb +14 -7
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +8 -27
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/migration/command_recorder.rb +54 -22
- data/lib/active_record/migration/compatibility.rb +79 -52
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +104 -85
- data/lib/active_record/model_schema.rb +62 -11
- data/lib/active_record/nested_attributes.rb +2 -4
- data/lib/active_record/no_touching.rb +9 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +232 -29
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +33 -21
- 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 +199 -46
- data/lib/active_record/reflection.rb +51 -51
- data/lib/active_record/relation/batches.rb +13 -11
- data/lib/active_record/relation/calculations.rb +55 -49
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +23 -28
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +12 -17
- 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/predicate_builder.rb +5 -11
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +232 -69
- data/lib/active_record/relation/spawn_methods.rb +1 -2
- data/lib/active_record/relation/where_clause.rb +14 -11
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/relation.rb +326 -81
- data/lib/active_record/result.rb +30 -12
- 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 +6 -2
- data/lib/active_record/scoping/default.rb +4 -6
- data/lib/active_record/scoping/named.rb +25 -16
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +23 -15
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +243 -0
- data/lib/active_record/timestamp.rb +39 -26
- data/lib/active_record/touch_later.rb +5 -4
- data/lib/active_record/transactions.rb +64 -73
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +0 -1
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +3 -5
- 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/associated.rb +0 -1
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record.rb +10 -2
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -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/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/nodes.rb +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +256 -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/depth_first.rb +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +62 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -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/migration.rb +14 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +116 -29
- data/lib/active_record/collection_cache_key.rb +0 -53
data/lib/active_record/result.rb
CHANGED
@@ -21,7 +21,7 @@ module ActiveRecord
|
|
21
21
|
# ]
|
22
22
|
#
|
23
23
|
# # Get an array of hashes representing the result (column => value):
|
24
|
-
# result.
|
24
|
+
# result.to_a
|
25
25
|
# # => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
|
26
26
|
# {"id" => 2, "title" => "title_2", "body" => "body_2"},
|
27
27
|
# ...
|
@@ -43,6 +43,11 @@ module ActiveRecord
|
|
43
43
|
@column_types = column_types
|
44
44
|
end
|
45
45
|
|
46
|
+
# Returns true if this result set includes the column named +name+
|
47
|
+
def includes_column?(name)
|
48
|
+
@columns.include? name
|
49
|
+
end
|
50
|
+
|
46
51
|
# Returns the number of elements in the rows array.
|
47
52
|
def length
|
48
53
|
@rows.length
|
@@ -60,9 +65,12 @@ module ActiveRecord
|
|
60
65
|
end
|
61
66
|
end
|
62
67
|
|
63
|
-
# Returns an array of hashes representing each row record.
|
64
68
|
def to_hash
|
65
|
-
|
69
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
70
|
+
`ActiveRecord::Result#to_hash` has been renamed to `to_a`.
|
71
|
+
`to_hash` is deprecated and will be removed in Rails 6.1.
|
72
|
+
MSG
|
73
|
+
to_a
|
66
74
|
end
|
67
75
|
|
68
76
|
alias :map! :map
|
@@ -78,6 +86,8 @@ module ActiveRecord
|
|
78
86
|
hash_rows
|
79
87
|
end
|
80
88
|
|
89
|
+
alias :to_a :to_ary
|
90
|
+
|
81
91
|
def [](idx)
|
82
92
|
hash_rows[idx]
|
83
93
|
end
|
@@ -97,12 +107,21 @@ module ActiveRecord
|
|
97
107
|
end
|
98
108
|
|
99
109
|
def cast_values(type_overrides = {}) # :nodoc:
|
100
|
-
|
101
|
-
|
102
|
-
types.zip(values).map { |type, value| type.deserialize(value) }
|
103
|
-
end
|
110
|
+
if columns.one?
|
111
|
+
# Separated to avoid allocating an array per row
|
104
112
|
|
105
|
-
|
113
|
+
type = column_type(columns.first, type_overrides)
|
114
|
+
|
115
|
+
rows.map do |(value)|
|
116
|
+
type.deserialize(value)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
types = columns.map { |name| column_type(name, type_overrides) }
|
120
|
+
|
121
|
+
rows.map do |values|
|
122
|
+
Array.new(values.size) { |i| types[i].deserialize(values[i]) }
|
123
|
+
end
|
124
|
+
end
|
106
125
|
end
|
107
126
|
|
108
127
|
def initialize_copy(other)
|
@@ -113,7 +132,6 @@ module ActiveRecord
|
|
113
132
|
end
|
114
133
|
|
115
134
|
private
|
116
|
-
|
117
135
|
def column_type(name, type_overrides = {})
|
118
136
|
type_overrides.fetch(name) do
|
119
137
|
column_types.fetch(name, Type.default_value)
|
@@ -125,7 +143,9 @@ module ActiveRecord
|
|
125
143
|
begin
|
126
144
|
# We freeze the strings to prevent them getting duped when
|
127
145
|
# used as keys in ActiveRecord::Base's @attributes hash
|
128
|
-
columns = @columns.map
|
146
|
+
columns = @columns.map(&:-@)
|
147
|
+
length = columns.length
|
148
|
+
|
129
149
|
@rows.map { |row|
|
130
150
|
# In the past we used Hash[columns.zip(row)]
|
131
151
|
# though elegant, the verbose way is much more efficient
|
@@ -134,8 +154,6 @@ module ActiveRecord
|
|
134
154
|
hash = {}
|
135
155
|
|
136
156
|
index = 0
|
137
|
-
length = columns.length
|
138
|
-
|
139
157
|
while index < length
|
140
158
|
hash[columns[index]] = row[index]
|
141
159
|
index += 1
|
@@ -61,8 +61,9 @@ module ActiveRecord
|
|
61
61
|
# # => "id ASC"
|
62
62
|
def sanitize_sql_for_order(condition)
|
63
63
|
if condition.is_a?(Array) && condition.first.to_s.include?("?")
|
64
|
-
|
65
|
-
|
64
|
+
disallow_raw_sql!(
|
65
|
+
[condition.first],
|
66
|
+
permit: connection.column_name_with_order_matcher
|
66
67
|
)
|
67
68
|
|
68
69
|
# Ensure we aren't dealing with a subclass of String that might
|
@@ -133,44 +134,34 @@ module ActiveRecord
|
|
133
134
|
end
|
134
135
|
end
|
135
136
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
# Given:
|
142
|
-
#
|
143
|
-
# class Person < ActiveRecord::Base
|
144
|
-
# composed_of :address, class_name: "Address",
|
145
|
-
# mapping: [%w(address_street street), %w(address_city city)]
|
146
|
-
# end
|
147
|
-
#
|
148
|
-
# Then:
|
149
|
-
#
|
150
|
-
# { address: Address.new("813 abc st.", "chicago") }
|
151
|
-
# # => { address_street: "813 abc st.", address_city: "chicago" }
|
152
|
-
def expand_hash_conditions_for_aggregates(attrs) # :doc:
|
153
|
-
expanded_attrs = {}
|
154
|
-
attrs.each do |attr, value|
|
155
|
-
if aggregation = reflect_on_aggregation(attr.to_sym)
|
156
|
-
mapping = aggregation.mapping
|
157
|
-
mapping.each do |field_attr, aggregate_attr|
|
158
|
-
expanded_attrs[field_attr] = if value.is_a?(Array)
|
159
|
-
value.map { |it| it.send(aggregate_attr) }
|
160
|
-
elsif mapping.size == 1 && !value.respond_to?(aggregate_attr)
|
161
|
-
value
|
162
|
-
else
|
163
|
-
value.send(aggregate_attr)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
else
|
167
|
-
expanded_attrs[attr] = value
|
168
|
-
end
|
169
|
-
end
|
170
|
-
expanded_attrs
|
137
|
+
def disallow_raw_sql!(args, permit: connection.column_name_matcher) # :nodoc:
|
138
|
+
unexpected = nil
|
139
|
+
args.each do |arg|
|
140
|
+
next if arg.is_a?(Symbol) || Arel.arel_node?(arg) || permit.match?(arg.to_s)
|
141
|
+
(unexpected ||= []) << arg
|
171
142
|
end
|
172
|
-
deprecate :expand_hash_conditions_for_aggregates
|
173
143
|
|
144
|
+
return unless unexpected
|
145
|
+
|
146
|
+
if allow_unsafe_raw_sql == :deprecated
|
147
|
+
ActiveSupport::Deprecation.warn(
|
148
|
+
"Dangerous query method (method whose arguments are used as raw " \
|
149
|
+
"SQL) called with non-attribute argument(s): " \
|
150
|
+
"#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
|
151
|
+
"arguments will be disallowed in Rails 6.1. This method should " \
|
152
|
+
"not be called with user-provided values, such as request " \
|
153
|
+
"parameters or model attributes. Known-safe values can be passed " \
|
154
|
+
"by wrapping them in Arel.sql()."
|
155
|
+
)
|
156
|
+
else
|
157
|
+
raise(ActiveRecord::UnknownAttributeReference,
|
158
|
+
"Query method called with non-attribute argument(s): " +
|
159
|
+
unexpected.map(&:inspect).join(", ")
|
160
|
+
)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
private
|
174
165
|
def replace_bind_variables(statement, values)
|
175
166
|
raise_if_bind_arity_mismatch(statement, statement.count("?"), values.size)
|
176
167
|
bound = values.dup
|
@@ -202,10 +193,11 @@ module ActiveRecord
|
|
202
193
|
|
203
194
|
def quote_bound_value(value, c = connection)
|
204
195
|
if value.respond_to?(:map) && !value.acts_like?(:string)
|
205
|
-
|
196
|
+
quoted = value.map { |v| c.quote(v) }
|
197
|
+
if quoted.empty?
|
206
198
|
c.quote(nil)
|
207
199
|
else
|
208
|
-
|
200
|
+
quoted.join(",")
|
209
201
|
end
|
210
202
|
else
|
211
203
|
c.quote(value)
|
data/lib/active_record/schema.rb
CHANGED
@@ -50,21 +50,12 @@ module ActiveRecord
|
|
50
50
|
instance_eval(&block)
|
51
51
|
|
52
52
|
if info[:version].present?
|
53
|
-
|
54
|
-
connection.assume_migrated_upto_version(info[:version]
|
53
|
+
connection.schema_migration.create_table
|
54
|
+
connection.assume_migrated_upto_version(info[:version])
|
55
55
|
end
|
56
56
|
|
57
57
|
ActiveRecord::InternalMetadata.create_table
|
58
58
|
ActiveRecord::InternalMetadata[:environment] = connection.migration_context.current_environment
|
59
59
|
end
|
60
|
-
|
61
|
-
private
|
62
|
-
# Returns the migrations paths.
|
63
|
-
#
|
64
|
-
# ActiveRecord::Schema.new.migrations_paths
|
65
|
-
# # => ["db/migrate"] # Rails migration path by default.
|
66
|
-
def migrations_paths
|
67
|
-
ActiveRecord::Migrator.migrations_paths
|
68
|
-
end
|
69
60
|
end
|
70
61
|
end
|
@@ -17,6 +17,12 @@ module ActiveRecord
|
|
17
17
|
# Only strings are accepted if ActiveRecord::Base.schema_format == :sql.
|
18
18
|
cattr_accessor :ignore_tables, default: []
|
19
19
|
|
20
|
+
##
|
21
|
+
# :singleton-method:
|
22
|
+
# Specify a custom regular expression matching foreign keys which name
|
23
|
+
# should not be dumped to db/schema.rb.
|
24
|
+
cattr_accessor :fk_ignore_pattern, default: /^fk_rails_[0-9a-f]{10}$/
|
25
|
+
|
20
26
|
class << self
|
21
27
|
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
|
22
28
|
connection.create_schema_dumper(generate_options(config)).dump(stream)
|
@@ -41,6 +47,7 @@ module ActiveRecord
|
|
41
47
|
end
|
42
48
|
|
43
49
|
private
|
50
|
+
attr_accessor :table_name
|
44
51
|
|
45
52
|
def initialize(connection, options = {})
|
46
53
|
@connection = connection
|
@@ -65,11 +72,11 @@ module ActiveRecord
|
|
65
72
|
# of editing this file, please use the migrations feature of Active Record to
|
66
73
|
# incrementally modify your database, and then regenerate this schema definition.
|
67
74
|
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
# from scratch.
|
72
|
-
#
|
75
|
+
# This file is the source Rails uses to define your schema when running `rails
|
76
|
+
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
|
77
|
+
# be faster and is potentially less error prone than running all of your
|
78
|
+
# migrations from scratch. Old migrations may fail to apply correctly if those
|
79
|
+
# migrations use external dependencies or application code.
|
73
80
|
#
|
74
81
|
# It's strongly recommended that you check this file into your version control system.
|
75
82
|
|
@@ -104,6 +111,8 @@ HEADER
|
|
104
111
|
def table(table, stream)
|
105
112
|
columns = @connection.columns(table)
|
106
113
|
begin
|
114
|
+
self.table_name = table
|
115
|
+
|
107
116
|
tbl = StringIO.new
|
108
117
|
|
109
118
|
# first dump primary key column
|
@@ -137,7 +146,11 @@ HEADER
|
|
137
146
|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
138
147
|
next if column.name == pk
|
139
148
|
type, colspec = column_spec(column)
|
140
|
-
|
149
|
+
if type.is_a?(Symbol)
|
150
|
+
tbl.print " t.#{type} #{column.name.inspect}"
|
151
|
+
else
|
152
|
+
tbl.print " t.column #{column.name.inspect}, #{type.inspect}"
|
153
|
+
end
|
141
154
|
tbl.print ", #{format_colspec(colspec)}" if colspec.present?
|
142
155
|
tbl.puts
|
143
156
|
end
|
@@ -153,6 +166,8 @@ HEADER
|
|
153
166
|
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
|
154
167
|
stream.puts "# #{e.message}"
|
155
168
|
stream.puts
|
169
|
+
ensure
|
170
|
+
self.table_name = nil
|
156
171
|
end
|
157
172
|
end
|
158
173
|
|
@@ -210,7 +225,7 @@ HEADER
|
|
210
225
|
parts << "primary_key: #{foreign_key.primary_key.inspect}"
|
211
226
|
end
|
212
227
|
|
213
|
-
if foreign_key.
|
228
|
+
if foreign_key.export_name_on_schema_dump?
|
214
229
|
parts << "name: #{foreign_key.name.inspect}"
|
215
230
|
end
|
216
231
|
|
@@ -10,12 +10,16 @@ module ActiveRecord
|
|
10
10
|
# to be executed the next time.
|
11
11
|
class SchemaMigration < ActiveRecord::Base # :nodoc:
|
12
12
|
class << self
|
13
|
+
def _internal?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
13
17
|
def primary_key
|
14
18
|
"version"
|
15
19
|
end
|
16
20
|
|
17
21
|
def table_name
|
18
|
-
"#{table_name_prefix}#{
|
22
|
+
"#{table_name_prefix}#{schema_migrations_table_name}#{table_name_suffix}"
|
19
23
|
end
|
20
24
|
|
21
25
|
def table_exists?
|
@@ -27,7 +31,7 @@ module ActiveRecord
|
|
27
31
|
version_options = connection.internal_string_options_for_primary_key
|
28
32
|
|
29
33
|
connection.create_table(table_name, id: false) do |t|
|
30
|
-
t.string :version, version_options
|
34
|
+
t.string :version, **version_options
|
31
35
|
end
|
32
36
|
end
|
33
37
|
end
|
@@ -44,7 +44,6 @@ module ActiveRecord
|
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
47
|
-
|
48
47
|
# Use this macro in your model to set a default scope for all operations on
|
49
48
|
# the model.
|
50
49
|
#
|
@@ -100,7 +99,7 @@ module ActiveRecord
|
|
100
99
|
self.default_scopes += [scope]
|
101
100
|
end
|
102
101
|
|
103
|
-
def build_default_scope(
|
102
|
+
def build_default_scope(relation = relation())
|
104
103
|
return if abstract_class?
|
105
104
|
|
106
105
|
if default_scope_override.nil?
|
@@ -111,15 +110,14 @@ module ActiveRecord
|
|
111
110
|
# The user has defined their own default scope method, so call that
|
112
111
|
evaluate_default_scope do
|
113
112
|
if scope = default_scope
|
114
|
-
|
113
|
+
relation.merge!(scope)
|
115
114
|
end
|
116
115
|
end
|
117
116
|
elsif default_scopes.any?
|
118
|
-
base_rel ||= relation
|
119
117
|
evaluate_default_scope do
|
120
|
-
default_scopes.inject(
|
118
|
+
default_scopes.inject(relation) do |default_scope, scope|
|
121
119
|
scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
|
122
|
-
default_scope.
|
120
|
+
default_scope.instance_exec(&scope) || default_scope
|
123
121
|
end
|
124
122
|
end
|
125
123
|
end
|
@@ -24,13 +24,21 @@ module ActiveRecord
|
|
24
24
|
# You can define a scope that applies to all finders using
|
25
25
|
# {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope].
|
26
26
|
def all
|
27
|
-
|
27
|
+
scope = current_scope
|
28
|
+
|
29
|
+
if scope
|
30
|
+
if scope._deprecated_scope_source
|
31
|
+
ActiveSupport::Deprecation.warn(<<~MSG.squish)
|
32
|
+
Class level methods will no longer inherit scoping from `#{scope._deprecated_scope_source}`
|
33
|
+
in Rails 6.1. To continue using the scoped relation, pass it into the block directly.
|
34
|
+
To instead access the full set of models, as Rails 6.1 will, use `#{name}.default_scoped`.
|
35
|
+
MSG
|
36
|
+
end
|
28
37
|
|
29
|
-
|
30
|
-
|
31
|
-
current_scope.clone
|
38
|
+
if self == scope.klass
|
39
|
+
scope.clone
|
32
40
|
else
|
33
|
-
relation.merge!(
|
41
|
+
relation.merge!(scope)
|
34
42
|
end
|
35
43
|
else
|
36
44
|
default_scoped
|
@@ -38,21 +46,20 @@ module ActiveRecord
|
|
38
46
|
end
|
39
47
|
|
40
48
|
def scope_for_association(scope = relation) # :nodoc:
|
41
|
-
|
42
|
-
|
43
|
-
if current_scope && current_scope.empty_scope?
|
49
|
+
if current_scope&.empty_scope?
|
44
50
|
scope
|
45
51
|
else
|
46
52
|
default_scoped(scope)
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
50
|
-
|
56
|
+
# Returns a scope for the model with default scopes.
|
57
|
+
def default_scoped(scope = relation)
|
51
58
|
build_default_scope(scope) || scope
|
52
59
|
end
|
53
60
|
|
54
61
|
def default_extensions # :nodoc:
|
55
|
-
if scope =
|
62
|
+
if scope = scope_for_association || build_default_scope
|
56
63
|
scope.extensions
|
57
64
|
else
|
58
65
|
[]
|
@@ -181,25 +188,27 @@ module ActiveRecord
|
|
181
188
|
extension = Module.new(&block) if block
|
182
189
|
|
183
190
|
if body.respond_to?(:to_proc)
|
184
|
-
singleton_class.
|
185
|
-
scope = all
|
186
|
-
scope = scope._exec_scope(*args, &body)
|
191
|
+
singleton_class.define_method(name) do |*args|
|
192
|
+
scope = all._exec_scope(name, *args, &body)
|
187
193
|
scope = scope.extending(extension) if extension
|
188
194
|
scope
|
189
195
|
end
|
190
196
|
else
|
191
|
-
singleton_class.
|
192
|
-
scope = all
|
193
|
-
scope = scope.scoping { body.call(*args) || scope }
|
197
|
+
singleton_class.define_method(name) do |*args|
|
198
|
+
scope = body.call(*args) || all
|
194
199
|
scope = scope.extending(extension) if extension
|
195
200
|
scope
|
196
201
|
end
|
197
202
|
end
|
203
|
+
singleton_class.send(:ruby2_keywords, name) if respond_to?(:ruby2_keywords, true)
|
198
204
|
|
199
205
|
generate_relation_method(name)
|
200
206
|
end
|
201
207
|
|
202
208
|
private
|
209
|
+
def singleton_method_added(name)
|
210
|
+
generate_relation_method(name) if Kernel.respond_to?(name) && !ActiveRecord::Relation.method_defined?(name)
|
211
|
+
end
|
203
212
|
|
204
213
|
def valid_scope_name?(name)
|
205
214
|
if respond_to?(name, true) && logger
|
@@ -12,14 +12,6 @@ module ActiveRecord
|
|
12
12
|
end
|
13
13
|
|
14
14
|
module ClassMethods # :nodoc:
|
15
|
-
def current_scope(skip_inherited_scope = false)
|
16
|
-
ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
|
17
|
-
end
|
18
|
-
|
19
|
-
def current_scope=(scope)
|
20
|
-
ScopeRegistry.set_value_for(:current_scope, self, scope)
|
21
|
-
end
|
22
|
-
|
23
15
|
# Collects attributes from scopes that should be applied when creating
|
24
16
|
# an AR instance for the particular class this is called on.
|
25
17
|
def scope_attributes
|
@@ -30,6 +22,14 @@ module ActiveRecord
|
|
30
22
|
def scope_attributes?
|
31
23
|
current_scope
|
32
24
|
end
|
25
|
+
|
26
|
+
def current_scope(skip_inherited_scope = false)
|
27
|
+
ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
|
28
|
+
end
|
29
|
+
|
30
|
+
def current_scope=(scope)
|
31
|
+
ScopeRegistry.set_value_for(:current_scope, self, scope)
|
32
|
+
end
|
33
33
|
end
|
34
34
|
|
35
35
|
def populate_with_current_scope_attributes # :nodoc:
|
@@ -95,7 +95,6 @@ module ActiveRecord
|
|
95
95
|
end
|
96
96
|
|
97
97
|
private
|
98
|
-
|
99
98
|
def raise_invalid_scope_type!(scope_type)
|
100
99
|
if !VALID_SCOPE_TYPES.include?(scope_type)
|
101
100
|
raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
|
@@ -44,7 +44,7 @@ module ActiveRecord
|
|
44
44
|
def initialize(values)
|
45
45
|
@values = values
|
46
46
|
@indexes = values.each_with_index.find_all { |thing, i|
|
47
|
-
|
47
|
+
Substitute === thing
|
48
48
|
}.map(&:last)
|
49
49
|
end
|
50
50
|
|
@@ -56,6 +56,28 @@ module ActiveRecord
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
class PartialQueryCollector
|
60
|
+
def initialize
|
61
|
+
@parts = []
|
62
|
+
@binds = []
|
63
|
+
end
|
64
|
+
|
65
|
+
def <<(str)
|
66
|
+
@parts << str
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_bind(obj)
|
71
|
+
@binds << obj
|
72
|
+
@parts << Substitute.new
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
def value
|
77
|
+
[@parts, @binds]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
59
81
|
def self.query(sql)
|
60
82
|
Query.new(sql)
|
61
83
|
end
|
@@ -64,6 +86,10 @@ module ActiveRecord
|
|
64
86
|
PartialQuery.new(values)
|
65
87
|
end
|
66
88
|
|
89
|
+
def self.partial_query_collector
|
90
|
+
PartialQueryCollector.new
|
91
|
+
end
|
92
|
+
|
67
93
|
class Params # :nodoc:
|
68
94
|
def bind; Substitute.new; end
|
69
95
|
end
|
@@ -106,6 +132,8 @@ module ActiveRecord
|
|
106
132
|
sql = query_builder.sql_for bind_values, connection
|
107
133
|
|
108
134
|
klass.find_by_sql(sql, bind_values, preparable: true, &block)
|
135
|
+
rescue ::RangeError
|
136
|
+
nil
|
109
137
|
end
|
110
138
|
|
111
139
|
def self.unsupported_value?(value)
|
@@ -114,8 +142,7 @@ module ActiveRecord
|
|
114
142
|
end
|
115
143
|
end
|
116
144
|
|
117
|
-
|
118
|
-
|
145
|
+
private
|
119
146
|
attr_reader :query_builder, :bind_map, :klass
|
120
147
|
end
|
121
148
|
end
|