activerecord 5.2.1.1 → 6.0.1
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 +738 -445
- 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/association_relation.rb +18 -9
- data/lib/active_record/associations.rb +20 -15
- data/lib/active_record/associations/association.rb +69 -20
- 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 +15 -29
- data/lib/active_record/associations/collection_proxy.rb +19 -48
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +11 -10
- data/lib/active_record/associations/has_many_through_association.rb +42 -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 +28 -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 +114 -38
- 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 +27 -13
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +6 -20
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +140 -27
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +22 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +116 -127
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +26 -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 +135 -56
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
- data/lib/active_record/connection_adapters/abstract_adapter.rb +189 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +151 -198
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +55 -45
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +9 -4
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +75 -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 +26 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +8 -2
- 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/money.rb +2 -2
- 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 +47 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +65 -77
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql/utils.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +172 -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 +120 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +45 -5
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +131 -143
- data/lib/active_record/connection_handling.rb +155 -26
- data/lib/active_record/core.rb +104 -59
- data/lib/active_record/counter_cache.rb +4 -29
- data/lib/active_record/database_configurations.rb +233 -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 +38 -7
- data/lib/active_record/errors.rb +30 -16
- 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 +145 -472
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +13 -3
- data/lib/active_record/insert_all.rb +179 -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 +88 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +100 -81
- data/lib/active_record/migration/command_recorder.rb +50 -6
- data/lib/active_record/migration/compatibility.rb +91 -64
- data/lib/active_record/model_schema.rb +34 -10
- data/lib/active_record/nested_attributes.rb +2 -2
- data/lib/active_record/no_touching.rb +7 -0
- data/lib/active_record/persistence.rb +233 -28
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +33 -21
- data/lib/active_record/railtie.rb +81 -46
- 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 +196 -46
- data/lib/active_record/reflection.rb +42 -44
- data/lib/active_record/relation.rb +320 -70
- data/lib/active_record/relation/batches.rb +13 -10
- data/lib/active_record/relation/calculations.rb +67 -57
- data/lib/active_record/relation/delegation.rb +48 -35
- data/lib/active_record/relation/finder_methods.rb +30 -30
- data/lib/active_record/relation/merger.rb +19 -25
- data/lib/active_record/relation/predicate_builder.rb +18 -15
- data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -6
- 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 +17 -10
- data/lib/active_record/relation/query_methods.rb +236 -73
- 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 +21 -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 +195 -26
- 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 +23 -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 +57 -66
- 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.rb +1 -0
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/arel.rb +58 -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 +111 -27
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -14,6 +14,8 @@ module ActiveRecord
|
|
14
14
|
# * change_column
|
15
15
|
# * change_column_default (must supply a :from and :to option)
|
16
16
|
# * change_column_null
|
17
|
+
# * change_column_comment (must supply a :from and :to option)
|
18
|
+
# * change_table_comment (must supply a :from and :to option)
|
17
19
|
# * create_join_table
|
18
20
|
# * create_table
|
19
21
|
# * disable_extension
|
@@ -35,7 +37,8 @@ module ActiveRecord
|
|
35
37
|
:change_column_default, :add_reference, :remove_reference, :transaction,
|
36
38
|
:drop_join_table, :drop_table, :execute_block, :enable_extension, :disable_extension,
|
37
39
|
:change_column, :execute, :remove_columns, :change_column_null,
|
38
|
-
:add_foreign_key, :remove_foreign_key
|
40
|
+
:add_foreign_key, :remove_foreign_key,
|
41
|
+
:change_column_comment, :change_table_comment
|
39
42
|
]
|
40
43
|
include JoinTable
|
41
44
|
|
@@ -85,7 +88,7 @@ module ActiveRecord
|
|
85
88
|
# invert the +command+.
|
86
89
|
def inverse_of(command, args, &block)
|
87
90
|
method = :"invert_#{command}"
|
88
|
-
raise IrreversibleMigration,
|
91
|
+
raise IrreversibleMigration, <<~MSG unless respond_to?(method, true)
|
89
92
|
This migration uses #{command}, which is not automatically reversible.
|
90
93
|
To make the migration reversible you can either:
|
91
94
|
1. Define #up and #down methods in place of the #change method.
|
@@ -108,11 +111,17 @@ module ActiveRecord
|
|
108
111
|
yield delegate.update_table_definition(table_name, self)
|
109
112
|
end
|
110
113
|
|
114
|
+
def replay(migration)
|
115
|
+
commands.each do |cmd, args, block|
|
116
|
+
migration.send(cmd, *args, &block)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
111
120
|
private
|
112
121
|
|
113
122
|
module StraightReversions # :nodoc:
|
114
123
|
private
|
115
|
-
{
|
124
|
+
{
|
116
125
|
execute_block: :execute_block,
|
117
126
|
create_table: :drop_table,
|
118
127
|
create_join_table: :drop_join_table,
|
@@ -133,6 +142,17 @@ module ActiveRecord
|
|
133
142
|
|
134
143
|
include StraightReversions
|
135
144
|
|
145
|
+
def invert_transaction(args)
|
146
|
+
sub_recorder = CommandRecorder.new(delegate)
|
147
|
+
sub_recorder.revert { yield }
|
148
|
+
|
149
|
+
invertions_proc = proc {
|
150
|
+
sub_recorder.replay(self)
|
151
|
+
}
|
152
|
+
|
153
|
+
[:transaction, args, invertions_proc]
|
154
|
+
end
|
155
|
+
|
136
156
|
def invert_drop_table(args, &block)
|
137
157
|
if args.size == 1 && block == nil
|
138
158
|
raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
|
@@ -214,15 +234,39 @@ module ActiveRecord
|
|
214
234
|
end
|
215
235
|
|
216
236
|
def invert_remove_foreign_key(args)
|
217
|
-
|
218
|
-
|
237
|
+
options = args.extract_options!
|
238
|
+
from_table, to_table = args
|
239
|
+
|
240
|
+
to_table ||= options.delete(:to_table)
|
241
|
+
|
242
|
+
raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil?
|
219
243
|
|
220
244
|
reversed_args = [from_table, to_table]
|
221
|
-
reversed_args <<
|
245
|
+
reversed_args << options unless options.empty?
|
222
246
|
|
223
247
|
[:add_foreign_key, reversed_args]
|
224
248
|
end
|
225
249
|
|
250
|
+
def invert_change_column_comment(args)
|
251
|
+
table, column, options = *args
|
252
|
+
|
253
|
+
unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
|
254
|
+
raise ActiveRecord::IrreversibleMigration, "change_column_comment is only reversible if given a :from and :to option."
|
255
|
+
end
|
256
|
+
|
257
|
+
[:change_column_comment, [table, column, from: options[:to], to: options[:from]]]
|
258
|
+
end
|
259
|
+
|
260
|
+
def invert_change_table_comment(args)
|
261
|
+
table, options = *args
|
262
|
+
|
263
|
+
unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
|
264
|
+
raise ActiveRecord::IrreversibleMigration, "change_table_comment is only reversible if given a :from and :to option."
|
265
|
+
end
|
266
|
+
|
267
|
+
[:change_table_comment, [table, from: options[:to], to: options[:from]]]
|
268
|
+
end
|
269
|
+
|
226
270
|
def respond_to_missing?(method, _)
|
227
271
|
super || delegate.respond_to?(method)
|
228
272
|
end
|
@@ -13,24 +13,92 @@ module ActiveRecord
|
|
13
13
|
const_get(name)
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
V6_0 = Current
|
17
|
+
|
18
|
+
class V5_2 < V6_0
|
19
|
+
module TableDefinition
|
20
|
+
def timestamps(**options)
|
21
|
+
options[:precision] ||= nil
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module CommandRecorder
|
27
|
+
def invert_transaction(args, &block)
|
28
|
+
[:transaction, args, block]
|
29
|
+
end
|
30
|
+
|
31
|
+
def invert_change_column_comment(args)
|
32
|
+
table_name, column_name, comment = args
|
33
|
+
[:change_column_comment, [table_name, column_name, from: comment, to: comment]]
|
34
|
+
end
|
35
|
+
|
36
|
+
def invert_change_table_comment(args)
|
37
|
+
table_name, comment = args
|
38
|
+
[:change_table_comment, [table_name, from: comment, to: comment]]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_table(table_name, **options)
|
43
|
+
if block_given?
|
44
|
+
super { |t| yield compatible_table_definition(t) }
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def change_table(table_name, **options)
|
51
|
+
if block_given?
|
52
|
+
super { |t| yield compatible_table_definition(t) }
|
53
|
+
else
|
54
|
+
super
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_join_table(table_1, table_2, **options)
|
59
|
+
if block_given?
|
60
|
+
super { |t| yield compatible_table_definition(t) }
|
61
|
+
else
|
62
|
+
super
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_timestamps(table_name, **options)
|
67
|
+
options[:precision] ||= nil
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def compatible_table_definition(t)
|
73
|
+
class << t
|
74
|
+
prepend TableDefinition
|
75
|
+
end
|
76
|
+
t
|
77
|
+
end
|
78
|
+
|
79
|
+
def command_recorder
|
80
|
+
recorder = super
|
81
|
+
class << recorder
|
82
|
+
prepend CommandRecorder
|
83
|
+
end
|
84
|
+
recorder
|
85
|
+
end
|
86
|
+
end
|
17
87
|
|
18
88
|
class V5_1 < V5_2
|
19
89
|
def change_column(table_name, column_name, type, options = {})
|
20
|
-
if adapter_name == "PostgreSQL"
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
|
26
|
-
change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
|
90
|
+
if connection.adapter_name == "PostgreSQL"
|
91
|
+
super(table_name, column_name, type, options.except(:default, :null, :comment))
|
92
|
+
connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
|
93
|
+
connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
|
94
|
+
connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
|
27
95
|
else
|
28
96
|
super
|
29
97
|
end
|
30
98
|
end
|
31
99
|
|
32
100
|
def create_table(table_name, options = {})
|
33
|
-
if adapter_name == "Mysql2"
|
101
|
+
if connection.adapter_name == "Mysql2"
|
34
102
|
super(table_name, options: "ENGINE=InnoDB", **options)
|
35
103
|
else
|
36
104
|
super
|
@@ -52,13 +120,13 @@ module ActiveRecord
|
|
52
120
|
end
|
53
121
|
|
54
122
|
def create_table(table_name, options = {})
|
55
|
-
if adapter_name == "PostgreSQL"
|
123
|
+
if connection.adapter_name == "PostgreSQL"
|
56
124
|
if options[:id] == :uuid && !options.key?(:default)
|
57
125
|
options[:default] = "uuid_generate_v4()"
|
58
126
|
end
|
59
127
|
end
|
60
128
|
|
61
|
-
unless adapter_name == "Mysql2" && options[:id] == :bigint
|
129
|
+
unless connection.adapter_name == "Mysql2" && options[:id] == :bigint
|
62
130
|
if [:integer, :bigint].include?(options[:id]) && !options.key?(:default)
|
63
131
|
options[:default] = nil
|
64
132
|
end
|
@@ -71,35 +139,12 @@ module ActiveRecord
|
|
71
139
|
options[:id] = :integer
|
72
140
|
end
|
73
141
|
|
74
|
-
|
75
|
-
super do |t|
|
76
|
-
yield compatible_table_definition(t)
|
77
|
-
end
|
78
|
-
else
|
79
|
-
super
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def change_table(table_name, options = {})
|
84
|
-
if block_given?
|
85
|
-
super do |t|
|
86
|
-
yield compatible_table_definition(t)
|
87
|
-
end
|
88
|
-
else
|
89
|
-
super
|
90
|
-
end
|
142
|
+
super
|
91
143
|
end
|
92
144
|
|
93
145
|
def create_join_table(table_1, table_2, column_options: {}, **options)
|
94
146
|
column_options.reverse_merge!(type: :integer)
|
95
|
-
|
96
|
-
if block_given?
|
97
|
-
super do |t|
|
98
|
-
yield compatible_table_definition(t)
|
99
|
-
end
|
100
|
-
else
|
101
|
-
super
|
102
|
-
end
|
147
|
+
super
|
103
148
|
end
|
104
149
|
|
105
150
|
def add_column(table_name, column_name, type, options = {})
|
@@ -120,7 +165,7 @@ module ActiveRecord
|
|
120
165
|
class << t
|
121
166
|
prepend TableDefinition
|
122
167
|
end
|
123
|
-
|
168
|
+
super
|
124
169
|
end
|
125
170
|
end
|
126
171
|
|
@@ -138,33 +183,13 @@ module ActiveRecord
|
|
138
183
|
end
|
139
184
|
end
|
140
185
|
|
141
|
-
def
|
142
|
-
if block_given?
|
143
|
-
super do |t|
|
144
|
-
yield compatible_table_definition(t)
|
145
|
-
end
|
146
|
-
else
|
147
|
-
super
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def change_table(table_name, options = {})
|
152
|
-
if block_given?
|
153
|
-
super do |t|
|
154
|
-
yield compatible_table_definition(t)
|
155
|
-
end
|
156
|
-
else
|
157
|
-
super
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def add_reference(*, **options)
|
186
|
+
def add_reference(table_name, ref_name, **options)
|
162
187
|
options[:index] ||= false
|
163
188
|
super
|
164
189
|
end
|
165
190
|
alias :add_belongs_to :add_reference
|
166
191
|
|
167
|
-
def add_timestamps(
|
192
|
+
def add_timestamps(table_name, **options)
|
168
193
|
options[:null] = true if options[:null].nil?
|
169
194
|
super
|
170
195
|
end
|
@@ -175,7 +200,7 @@ module ActiveRecord
|
|
175
200
|
if options[:name].present?
|
176
201
|
options[:name].to_s
|
177
202
|
else
|
178
|
-
index_name(table_name, column: column_names)
|
203
|
+
connection.index_name(table_name, column: column_names)
|
179
204
|
end
|
180
205
|
super
|
181
206
|
end
|
@@ -195,15 +220,17 @@ module ActiveRecord
|
|
195
220
|
end
|
196
221
|
|
197
222
|
def index_name_for_remove(table_name, options = {})
|
198
|
-
index_name = index_name(table_name, options)
|
223
|
+
index_name = connection.index_name(table_name, options)
|
199
224
|
|
200
|
-
unless index_name_exists?(table_name, index_name)
|
225
|
+
unless connection.index_name_exists?(table_name, index_name)
|
201
226
|
if options.is_a?(Hash) && options.has_key?(:name)
|
202
227
|
options_without_column = options.dup
|
203
228
|
options_without_column.delete :column
|
204
|
-
index_name_without_column = index_name(table_name, options_without_column)
|
229
|
+
index_name_without_column = connection.index_name(table_name, options_without_column)
|
205
230
|
|
206
|
-
|
231
|
+
if connection.index_name_exists?(table_name, index_name_without_column)
|
232
|
+
return index_name_without_column
|
233
|
+
end
|
207
234
|
end
|
208
235
|
|
209
236
|
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
|
@@ -102,6 +102,21 @@ module ActiveRecord
|
|
102
102
|
# If true, the default table name for a Product class will be "products". If false, it would just be "product".
|
103
103
|
# See table_name for the full rules on table/class naming. This is true, by default.
|
104
104
|
|
105
|
+
##
|
106
|
+
# :singleton-method: implicit_order_column
|
107
|
+
# :call-seq: implicit_order_column
|
108
|
+
#
|
109
|
+
# The name of the column records are ordered by if no explicit order clause
|
110
|
+
# is used during an ordered finder call. If not set the primary key is used.
|
111
|
+
|
112
|
+
##
|
113
|
+
# :singleton-method: implicit_order_column=
|
114
|
+
# :call-seq: implicit_order_column=(column_name)
|
115
|
+
#
|
116
|
+
# Sets the column to sort records by when no explicit order clause is used
|
117
|
+
# during an ordered finder call. Useful when the primary key is not an
|
118
|
+
# auto-incrementing integer, for example when it's a UUID. Note that using
|
119
|
+
# a non-unique column can result in non-deterministic results.
|
105
120
|
included do
|
106
121
|
mattr_accessor :primary_key_prefix_type, instance_writer: false
|
107
122
|
|
@@ -110,6 +125,7 @@ module ActiveRecord
|
|
110
125
|
class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
|
111
126
|
class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
|
112
127
|
class_attribute :pluralize_table_names, instance_writer: false, default: true
|
128
|
+
class_attribute :implicit_order_column, instance_accessor: false
|
113
129
|
|
114
130
|
self.protected_environments = ["production"]
|
115
131
|
self.inheritance_column = "type"
|
@@ -218,11 +234,11 @@ module ActiveRecord
|
|
218
234
|
end
|
219
235
|
|
220
236
|
def full_table_name_prefix #:nodoc:
|
221
|
-
(
|
237
|
+
(module_parents.detect { |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
|
222
238
|
end
|
223
239
|
|
224
240
|
def full_table_name_suffix #:nodoc:
|
225
|
-
(
|
241
|
+
(module_parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
|
226
242
|
end
|
227
243
|
|
228
244
|
# The array of names of environments where destructive actions should be prohibited. By default,
|
@@ -276,7 +292,7 @@ module ActiveRecord
|
|
276
292
|
end
|
277
293
|
|
278
294
|
def sequence_name
|
279
|
-
if base_class
|
295
|
+
if base_class?
|
280
296
|
@sequence_name ||= reset_sequence_name
|
281
297
|
else
|
282
298
|
(@sequence_name ||= nil) || base_class.sequence_name
|
@@ -375,7 +391,7 @@ module ActiveRecord
|
|
375
391
|
# default values when instantiating the Active Record object for this table.
|
376
392
|
def column_defaults
|
377
393
|
load_schema
|
378
|
-
@column_defaults ||= _default_attributes.to_hash
|
394
|
+
@column_defaults ||= _default_attributes.deep_dup.to_hash
|
379
395
|
end
|
380
396
|
|
381
397
|
def _default_attributes # :nodoc:
|
@@ -388,6 +404,11 @@ module ActiveRecord
|
|
388
404
|
@column_names ||= columns.map(&:name)
|
389
405
|
end
|
390
406
|
|
407
|
+
def symbol_column_to_string(name_symbol) # :nodoc:
|
408
|
+
@symbol_column_to_string_name_hash ||= column_names.index_by(&:to_sym)
|
409
|
+
@symbol_column_to_string_name_hash[name_symbol]
|
410
|
+
end
|
411
|
+
|
391
412
|
# Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
|
392
413
|
# and columns used for single table inheritance have been removed.
|
393
414
|
def content_columns
|
@@ -459,6 +480,9 @@ module ActiveRecord
|
|
459
480
|
load_schema!
|
460
481
|
|
461
482
|
@schema_loaded = true
|
483
|
+
rescue
|
484
|
+
reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
|
485
|
+
raise
|
462
486
|
end
|
463
487
|
end
|
464
488
|
|
@@ -477,6 +501,7 @@ module ActiveRecord
|
|
477
501
|
def reload_schema_from_cache
|
478
502
|
@arel_table = nil
|
479
503
|
@column_names = nil
|
504
|
+
@symbol_column_to_string_name_hash = nil
|
480
505
|
@attribute_types = nil
|
481
506
|
@content_columns = nil
|
482
507
|
@default_attributes = nil
|
@@ -501,19 +526,18 @@ module ActiveRecord
|
|
501
526
|
|
502
527
|
# Computes and returns a table name according to default conventions.
|
503
528
|
def compute_table_name
|
504
|
-
|
505
|
-
if self == base
|
529
|
+
if base_class?
|
506
530
|
# Nested classes are prefixed with singular parent table name.
|
507
|
-
if
|
508
|
-
contained =
|
509
|
-
contained = contained.singularize if
|
531
|
+
if module_parent < Base && !module_parent.abstract_class?
|
532
|
+
contained = module_parent.table_name
|
533
|
+
contained = contained.singularize if module_parent.pluralize_table_names
|
510
534
|
contained += "_"
|
511
535
|
end
|
512
536
|
|
513
537
|
"#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
|
514
538
|
else
|
515
539
|
# STI subclasses always use their superclass' table.
|
516
|
-
|
540
|
+
base_class.table_name
|
517
541
|
end
|
518
542
|
end
|
519
543
|
end
|
@@ -426,7 +426,7 @@ module ActiveRecord
|
|
426
426
|
existing_record.assign_attributes(assignable_attributes)
|
427
427
|
association(association_name).initialize_attributes(existing_record)
|
428
428
|
else
|
429
|
-
method = "build_#{association_name}"
|
429
|
+
method = :"build_#{association_name}"
|
430
430
|
if respond_to?(method)
|
431
431
|
send(method, assignable_attributes)
|
432
432
|
else
|
@@ -501,7 +501,7 @@ module ActiveRecord
|
|
501
501
|
|
502
502
|
if attributes["id"].blank?
|
503
503
|
unless reject_new_record?(association_name, attributes)
|
504
|
-
association.build(attributes.except(*UNASSIGNABLE_KEYS))
|
504
|
+
association.reader.build(attributes.except(*UNASSIGNABLE_KEYS))
|
505
505
|
end
|
506
506
|
elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes["id"].to_s }
|
507
507
|
unless call_reject_if(association_name, attributes)
|