activerecord 5.2.6 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +609 -622
- data/MIT-LICENSE +3 -1
- data/README.rdoc +4 -2
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +4 -2
- 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 +3 -13
- 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 +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 +9 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/join_dependency.rb +24 -28
- 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/preloader.rb +40 -32
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations.rb +19 -14
- data/lib/active_record/attribute_assignment.rb +7 -10
- 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/attribute_methods.rb +28 -100
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +5 -9
- 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 +94 -16
- 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 +17 -8
- 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 +180 -47
- 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 +26 -9
- 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/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 +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 +125 -141
- 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/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/database_configurations.rb +233 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +37 -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 +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/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +50 -6
- data/lib/active_record/migration/compatibility.rb +76 -49
- data/lib/active_record/migration.rb +100 -81
- 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 +196 -46
- data/lib/active_record/reflection.rb +32 -30
- data/lib/active_record/relation/batches.rb +13 -10
- data/lib/active_record/relation/calculations.rb +53 -47
- data/lib/active_record/relation/delegation.rb +26 -43
- data/lib/active_record/relation/finder_methods.rb +13 -26
- data/lib/active_record/relation/merger.rb +11 -20
- 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 +4 -6
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +189 -63
- 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/relation.rb +310 -80
- 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/default.rb +4 -5
- data/lib/active_record/scoping/named.rb +19 -15
- data/lib/active_record/scoping.rb +8 -8
- data/lib/active_record/statement_cache.rb +30 -3
- 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 +194 -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 +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/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type.rb +3 -4
- 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/active_record/validations.rb +1 -0
- data/lib/active_record.rb +9 -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 +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/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/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +51 -0
- 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 -1
- 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 +108 -26
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "benchmark"
|
3
4
|
require "set"
|
4
5
|
require "zlib"
|
5
6
|
require "active_support/core_ext/module/attribute_accessors"
|
7
|
+
require "active_support/actionable_error"
|
6
8
|
|
7
9
|
module ActiveRecord
|
8
|
-
class MigrationError < ActiveRecordError#:nodoc:
|
10
|
+
class MigrationError < ActiveRecordError #:nodoc:
|
9
11
|
def initialize(message = nil)
|
10
12
|
message = "\n\n#{message}\n\n" if message
|
11
13
|
super
|
@@ -22,7 +24,7 @@ module ActiveRecord
|
|
22
24
|
# t.string :zipcode
|
23
25
|
# end
|
24
26
|
#
|
25
|
-
# execute
|
27
|
+
# execute <<~SQL
|
26
28
|
# ALTER TABLE distributors
|
27
29
|
# ADD CONSTRAINT zipchk
|
28
30
|
# CHECK (char_length(zipcode) = 5) NO INHERIT;
|
@@ -40,7 +42,7 @@ module ActiveRecord
|
|
40
42
|
# t.string :zipcode
|
41
43
|
# end
|
42
44
|
#
|
43
|
-
# execute
|
45
|
+
# execute <<~SQL
|
44
46
|
# ALTER TABLE distributors
|
45
47
|
# ADD CONSTRAINT zipchk
|
46
48
|
# CHECK (char_length(zipcode) = 5) NO INHERIT;
|
@@ -48,7 +50,7 @@ module ActiveRecord
|
|
48
50
|
# end
|
49
51
|
#
|
50
52
|
# def down
|
51
|
-
# execute
|
53
|
+
# execute <<~SQL
|
52
54
|
# ALTER TABLE distributors
|
53
55
|
# DROP CONSTRAINT zipchk
|
54
56
|
# SQL
|
@@ -67,7 +69,7 @@ module ActiveRecord
|
|
67
69
|
#
|
68
70
|
# reversible do |dir|
|
69
71
|
# dir.up do
|
70
|
-
# execute
|
72
|
+
# execute <<~SQL
|
71
73
|
# ALTER TABLE distributors
|
72
74
|
# ADD CONSTRAINT zipchk
|
73
75
|
# CHECK (char_length(zipcode) = 5) NO INHERIT;
|
@@ -75,7 +77,7 @@ module ActiveRecord
|
|
75
77
|
# end
|
76
78
|
#
|
77
79
|
# dir.down do
|
78
|
-
# execute
|
80
|
+
# execute <<~SQL
|
79
81
|
# ALTER TABLE distributors
|
80
82
|
# DROP CONSTRAINT zipchk
|
81
83
|
# SQL
|
@@ -86,7 +88,7 @@ module ActiveRecord
|
|
86
88
|
class IrreversibleMigration < MigrationError
|
87
89
|
end
|
88
90
|
|
89
|
-
class DuplicateMigrationVersionError < MigrationError#:nodoc:
|
91
|
+
class DuplicateMigrationVersionError < MigrationError #:nodoc:
|
90
92
|
def initialize(version = nil)
|
91
93
|
if version
|
92
94
|
super("Multiple migrations have the version number #{version}.")
|
@@ -96,7 +98,7 @@ module ActiveRecord
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
99
|
-
class DuplicateMigrationNameError < MigrationError#:nodoc:
|
101
|
+
class DuplicateMigrationNameError < MigrationError #:nodoc:
|
100
102
|
def initialize(name = nil)
|
101
103
|
if name
|
102
104
|
super("Multiple migrations have the name #{name}.")
|
@@ -116,7 +118,7 @@ module ActiveRecord
|
|
116
118
|
end
|
117
119
|
end
|
118
120
|
|
119
|
-
class IllegalMigrationNameError < MigrationError#:nodoc:
|
121
|
+
class IllegalMigrationNameError < MigrationError #:nodoc:
|
120
122
|
def initialize(name = nil)
|
121
123
|
if name
|
122
124
|
super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed).")
|
@@ -126,12 +128,18 @@ module ActiveRecord
|
|
126
128
|
end
|
127
129
|
end
|
128
130
|
|
129
|
-
class PendingMigrationError < MigrationError#:nodoc:
|
131
|
+
class PendingMigrationError < MigrationError #:nodoc:
|
132
|
+
include ActiveSupport::ActionableError
|
133
|
+
|
134
|
+
action "Run pending migrations" do
|
135
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
136
|
+
end
|
137
|
+
|
130
138
|
def initialize(message = nil)
|
131
139
|
if !message && defined?(Rails.env)
|
132
|
-
super("Migrations are pending. To resolve this issue, run:\n\n
|
140
|
+
super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate RAILS_ENV=#{::Rails.env}")
|
133
141
|
elsif !message
|
134
|
-
super("Migrations are pending. To resolve this issue, run:\n\n
|
142
|
+
super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate")
|
135
143
|
else
|
136
144
|
super
|
137
145
|
end
|
@@ -139,8 +147,8 @@ module ActiveRecord
|
|
139
147
|
end
|
140
148
|
|
141
149
|
class ConcurrentMigrationError < MigrationError #:nodoc:
|
142
|
-
DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running."
|
143
|
-
RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock"
|
150
|
+
DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running."
|
151
|
+
RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock"
|
144
152
|
|
145
153
|
def initialize(message = DEFAULT_MESSAGE)
|
146
154
|
super
|
@@ -149,7 +157,7 @@ module ActiveRecord
|
|
149
157
|
|
150
158
|
class NoEnvironmentInSchemaError < MigrationError #:nodoc:
|
151
159
|
def initialize
|
152
|
-
msg = "Environment data not found in the schema. To resolve this issue, run: \n\n
|
160
|
+
msg = "Environment data not found in the schema. To resolve this issue, run: \n\n rails db:environment:set"
|
153
161
|
if defined?(Rails.env)
|
154
162
|
super("#{msg} RAILS_ENV=#{::Rails.env}")
|
155
163
|
else
|
@@ -160,7 +168,7 @@ module ActiveRecord
|
|
160
168
|
|
161
169
|
class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
|
162
170
|
def initialize(env = "production")
|
163
|
-
msg = "You are attempting to run a destructive action against your '#{env}' database.\n"
|
171
|
+
msg = +"You are attempting to run a destructive action against your '#{env}' database.\n"
|
164
172
|
msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
|
165
173
|
msg << "DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
|
166
174
|
super(msg)
|
@@ -169,10 +177,10 @@ module ActiveRecord
|
|
169
177
|
|
170
178
|
class EnvironmentMismatchError < ActiveRecordError
|
171
179
|
def initialize(current: nil, stored: nil)
|
172
|
-
msg =
|
180
|
+
msg = +"You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
|
173
181
|
msg << "You are running in `#{ current }` environment. "
|
174
182
|
msg << "If you are sure you want to continue, first set the environment using:\n\n"
|
175
|
-
msg << "
|
183
|
+
msg << " rails db:environment:set"
|
176
184
|
if defined?(Rails.env)
|
177
185
|
super("#{msg} RAILS_ENV=#{::Rails.env}\n\n")
|
178
186
|
else
|
@@ -307,7 +315,7 @@ module ActiveRecord
|
|
307
315
|
# named +column_name+ from the table called +table_name+.
|
308
316
|
# * <tt>remove_columns(table_name, *column_names)</tt>: Removes the given
|
309
317
|
# columns from the table definition.
|
310
|
-
# * <tt>remove_foreign_key(from_table,
|
318
|
+
# * <tt>remove_foreign_key(from_table, to_table = nil, **options)</tt>: Removes the
|
311
319
|
# given foreign key from the table called +table_name+.
|
312
320
|
# * <tt>remove_index(table_name, column: column_names)</tt>: Removes the index
|
313
321
|
# specified by +column_names+.
|
@@ -351,7 +359,7 @@ module ActiveRecord
|
|
351
359
|
# <tt>rails db:migrate</tt>. This will update the database by running all of the
|
352
360
|
# pending migrations, creating the <tt>schema_migrations</tt> table
|
353
361
|
# (see "About the schema_migrations table" section below) if missing. It will also
|
354
|
-
# invoke the db:schema:dump
|
362
|
+
# invoke the db:schema:dump command, which will update your db/schema.rb file
|
355
363
|
# to match the structure of your database.
|
356
364
|
#
|
357
365
|
# To roll the database back to a previous migration version, use
|
@@ -486,9 +494,9 @@ module ActiveRecord
|
|
486
494
|
# This migration will create the horses table for you on the way up, and
|
487
495
|
# automatically figure out how to drop the table on the way down.
|
488
496
|
#
|
489
|
-
# Some commands
|
490
|
-
#
|
491
|
-
#
|
497
|
+
# Some commands cannot be reversed. If you care to define how to move up
|
498
|
+
# and down in these cases, you should define the +up+ and +down+ methods
|
499
|
+
# as before.
|
492
500
|
#
|
493
501
|
# If a command cannot be reversed, an
|
494
502
|
# <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
|
@@ -519,10 +527,10 @@ module ActiveRecord
|
|
519
527
|
autoload :Compatibility, "active_record/migration/compatibility"
|
520
528
|
|
521
529
|
# This must be defined before the inherited hook, below
|
522
|
-
class Current < Migration
|
530
|
+
class Current < Migration #:nodoc:
|
523
531
|
end
|
524
532
|
|
525
|
-
def self.inherited(subclass)
|
533
|
+
def self.inherited(subclass) #:nodoc:
|
526
534
|
super
|
527
535
|
if subclass.superclass == Migration
|
528
536
|
raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \
|
@@ -540,7 +548,7 @@ module ActiveRecord
|
|
540
548
|
ActiveRecord::VERSION::STRING.to_f
|
541
549
|
end
|
542
550
|
|
543
|
-
MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/
|
551
|
+
MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ #:nodoc:
|
544
552
|
|
545
553
|
# This class is used to verify that all migrations have been run before
|
546
554
|
# loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
|
@@ -567,10 +575,10 @@ module ActiveRecord
|
|
567
575
|
end
|
568
576
|
|
569
577
|
class << self
|
570
|
-
attr_accessor :delegate
|
571
|
-
attr_accessor :disable_ddl_transaction
|
578
|
+
attr_accessor :delegate #:nodoc:
|
579
|
+
attr_accessor :disable_ddl_transaction #:nodoc:
|
572
580
|
|
573
|
-
def nearest_delegate
|
581
|
+
def nearest_delegate #:nodoc:
|
574
582
|
delegate || superclass.nearest_delegate
|
575
583
|
end
|
576
584
|
|
@@ -580,27 +588,35 @@ module ActiveRecord
|
|
580
588
|
end
|
581
589
|
|
582
590
|
def load_schema_if_pending!
|
583
|
-
|
591
|
+
current_config = Base.connection_config
|
592
|
+
all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
|
593
|
+
|
594
|
+
needs_update = !all_configs.all? do |db_config|
|
595
|
+
Tasks::DatabaseTasks.schema_up_to_date?(db_config.config, ActiveRecord::Base.schema_format, nil, Rails.env, db_config.spec_name)
|
596
|
+
end
|
597
|
+
|
598
|
+
if needs_update
|
584
599
|
# Roundtrip to Rake to allow plugins to hook into database initialization.
|
585
600
|
root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
|
586
601
|
FileUtils.cd(root) do
|
587
|
-
current_config = Base.connection_config
|
588
602
|
Base.clear_all_connections!
|
589
603
|
system("bin/rails db:test:prepare")
|
590
|
-
# Establish a new connection, the old database may be gone (db:test:prepare uses purge)
|
591
|
-
Base.establish_connection(current_config)
|
592
604
|
end
|
593
|
-
check_pending!
|
594
605
|
end
|
606
|
+
|
607
|
+
# Establish a new connection, the old database may be gone (db:test:prepare uses purge)
|
608
|
+
Base.establish_connection(current_config)
|
609
|
+
|
610
|
+
check_pending!
|
595
611
|
end
|
596
612
|
|
597
|
-
def maintain_test_schema!
|
613
|
+
def maintain_test_schema! #:nodoc:
|
598
614
|
if ActiveRecord::Base.maintain_test_schema
|
599
615
|
suppress_messages { load_schema_if_pending! }
|
600
616
|
end
|
601
617
|
end
|
602
618
|
|
603
|
-
def method_missing(name, *args, &block)
|
619
|
+
def method_missing(name, *args, &block) #:nodoc:
|
604
620
|
nearest_delegate.send(name, *args, &block)
|
605
621
|
end
|
606
622
|
|
@@ -617,7 +633,7 @@ module ActiveRecord
|
|
617
633
|
end
|
618
634
|
end
|
619
635
|
|
620
|
-
def disable_ddl_transaction
|
636
|
+
def disable_ddl_transaction #:nodoc:
|
621
637
|
self.class.disable_ddl_transaction
|
622
638
|
end
|
623
639
|
|
@@ -677,15 +693,13 @@ module ActiveRecord
|
|
677
693
|
if connection.respond_to? :revert
|
678
694
|
connection.revert { yield }
|
679
695
|
else
|
680
|
-
recorder =
|
696
|
+
recorder = command_recorder
|
681
697
|
@connection = recorder
|
682
698
|
suppress_messages do
|
683
699
|
connection.revert { yield }
|
684
700
|
end
|
685
701
|
@connection = recorder.delegate
|
686
|
-
recorder.
|
687
|
-
send(cmd, *args, &block)
|
688
|
-
end
|
702
|
+
recorder.replay(self)
|
689
703
|
end
|
690
704
|
end
|
691
705
|
end
|
@@ -694,7 +708,7 @@ module ActiveRecord
|
|
694
708
|
connection.respond_to?(:reverting) && connection.reverting
|
695
709
|
end
|
696
710
|
|
697
|
-
ReversibleBlockHelper = Struct.new(:reverting) do
|
711
|
+
ReversibleBlockHelper = Struct.new(:reverting) do #:nodoc:
|
698
712
|
def up
|
699
713
|
yield unless reverting
|
700
714
|
end
|
@@ -830,10 +844,14 @@ module ActiveRecord
|
|
830
844
|
write "== %s %s" % [text, "=" * length]
|
831
845
|
end
|
832
846
|
|
847
|
+
# Takes a message argument and outputs it as is.
|
848
|
+
# A second boolean argument can be passed to specify whether to indent or not.
|
833
849
|
def say(message, subitem = false)
|
834
850
|
write "#{subitem ? " ->" : "--"} #{message}"
|
835
851
|
end
|
836
852
|
|
853
|
+
# Outputs text along with how long it took to run its block.
|
854
|
+
# If the block returns an integer it assumes it is the number of rows affected.
|
837
855
|
def say_with_time(message)
|
838
856
|
say(message)
|
839
857
|
result = nil
|
@@ -843,6 +861,7 @@ module ActiveRecord
|
|
843
861
|
result
|
844
862
|
end
|
845
863
|
|
864
|
+
# Takes a block as an argument and suppresses any output generated by the block.
|
846
865
|
def suppress_messages
|
847
866
|
save, self.verbose = verbose, false
|
848
867
|
yield
|
@@ -874,18 +893,19 @@ module ActiveRecord
|
|
874
893
|
|
875
894
|
def copy(destination, sources, options = {})
|
876
895
|
copied = []
|
896
|
+
schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
|
877
897
|
|
878
898
|
FileUtils.mkdir_p(destination) unless File.exist?(destination)
|
879
899
|
|
880
|
-
destination_migrations = ActiveRecord::MigrationContext.new(destination).migrations
|
900
|
+
destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
|
881
901
|
last = destination_migrations.last
|
882
902
|
sources.each do |scope, path|
|
883
|
-
source_migrations = ActiveRecord::MigrationContext.new(path).migrations
|
903
|
+
source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
|
884
904
|
|
885
905
|
source_migrations.each do |migration|
|
886
906
|
source = File.binread(migration.filename)
|
887
907
|
inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
|
888
|
-
magic_comments = ""
|
908
|
+
magic_comments = +""
|
889
909
|
loop do
|
890
910
|
# If we have a magic comment in the original migration,
|
891
911
|
# insert our comment after the first newline(end of the magic comment line)
|
@@ -956,6 +976,10 @@ module ActiveRecord
|
|
956
976
|
yield
|
957
977
|
end
|
958
978
|
end
|
979
|
+
|
980
|
+
def command_recorder
|
981
|
+
CommandRecorder.new(connection)
|
982
|
+
end
|
959
983
|
end
|
960
984
|
|
961
985
|
# MigrationProxy is used to defer loading of the actual migration classes
|
@@ -998,11 +1022,12 @@ module ActiveRecord
|
|
998
1022
|
end
|
999
1023
|
end
|
1000
1024
|
|
1001
|
-
class MigrationContext
|
1002
|
-
attr_reader :migrations_paths
|
1025
|
+
class MigrationContext #:nodoc:
|
1026
|
+
attr_reader :migrations_paths, :schema_migration
|
1003
1027
|
|
1004
|
-
def initialize(migrations_paths)
|
1028
|
+
def initialize(migrations_paths, schema_migration)
|
1005
1029
|
@migrations_paths = migrations_paths
|
1030
|
+
@schema_migration = schema_migration
|
1006
1031
|
end
|
1007
1032
|
|
1008
1033
|
def migrate(target_version = nil, &block)
|
@@ -1033,7 +1058,7 @@ module ActiveRecord
|
|
1033
1058
|
migrations
|
1034
1059
|
end
|
1035
1060
|
|
1036
|
-
Migrator.new(:up, selected_migrations, target_version).migrate
|
1061
|
+
Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
|
1037
1062
|
end
|
1038
1063
|
|
1039
1064
|
def down(target_version = nil)
|
@@ -1043,20 +1068,20 @@ module ActiveRecord
|
|
1043
1068
|
migrations
|
1044
1069
|
end
|
1045
1070
|
|
1046
|
-
Migrator.new(:down, selected_migrations, target_version).migrate
|
1071
|
+
Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
|
1047
1072
|
end
|
1048
1073
|
|
1049
1074
|
def run(direction, target_version)
|
1050
|
-
Migrator.new(direction, migrations, target_version).run
|
1075
|
+
Migrator.new(direction, migrations, schema_migration, target_version).run
|
1051
1076
|
end
|
1052
1077
|
|
1053
1078
|
def open
|
1054
|
-
Migrator.new(:up, migrations,
|
1079
|
+
Migrator.new(:up, migrations, schema_migration)
|
1055
1080
|
end
|
1056
1081
|
|
1057
1082
|
def get_all_versions
|
1058
|
-
if
|
1059
|
-
|
1083
|
+
if schema_migration.table_exists?
|
1084
|
+
schema_migration.all_versions.map(&:to_i)
|
1060
1085
|
else
|
1061
1086
|
[]
|
1062
1087
|
end
|
@@ -1079,10 +1104,6 @@ module ActiveRecord
|
|
1079
1104
|
migrations.last || NullMigration.new
|
1080
1105
|
end
|
1081
1106
|
|
1082
|
-
def parse_migration_filename(filename) # :nodoc:
|
1083
|
-
File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
|
1084
|
-
end
|
1085
|
-
|
1086
1107
|
def migrations
|
1087
1108
|
migrations = migration_files.map do |file|
|
1088
1109
|
version, name, scope = parse_migration_filename(file)
|
@@ -1097,12 +1118,12 @@ module ActiveRecord
|
|
1097
1118
|
end
|
1098
1119
|
|
1099
1120
|
def migrations_status
|
1100
|
-
db_list =
|
1121
|
+
db_list = schema_migration.normalized_versions
|
1101
1122
|
|
1102
1123
|
file_list = migration_files.map do |file|
|
1103
1124
|
version, name, scope = parse_migration_filename(file)
|
1104
1125
|
raise IllegalMigrationNameError.new(file) unless version
|
1105
|
-
version =
|
1126
|
+
version = schema_migration.normalize_migration_number(version)
|
1106
1127
|
status = db_list.delete(version) ? "up" : "down"
|
1107
1128
|
[status, version, (name + scope).humanize]
|
1108
1129
|
end.compact
|
@@ -1114,11 +1135,6 @@ module ActiveRecord
|
|
1114
1135
|
(db_list + file_list).sort_by { |_, version, _| version }
|
1115
1136
|
end
|
1116
1137
|
|
1117
|
-
def migration_files
|
1118
|
-
paths = Array(migrations_paths)
|
1119
|
-
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
1120
|
-
end
|
1121
|
-
|
1122
1138
|
def current_environment
|
1123
1139
|
ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
|
1124
1140
|
end
|
@@ -1137,8 +1153,17 @@ module ActiveRecord
|
|
1137
1153
|
end
|
1138
1154
|
|
1139
1155
|
private
|
1156
|
+
def migration_files
|
1157
|
+
paths = Array(migrations_paths)
|
1158
|
+
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
def parse_migration_filename(filename)
|
1162
|
+
File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
|
1163
|
+
end
|
1164
|
+
|
1140
1165
|
def move(direction, steps)
|
1141
|
-
migrator = Migrator.new(direction, migrations)
|
1166
|
+
migrator = Migrator.new(direction, migrations, schema_migration)
|
1142
1167
|
|
1143
1168
|
if current_version != 0 && !migrator.current_migration
|
1144
1169
|
raise UnknownMigrationVersionError.new(current_version)
|
@@ -1161,30 +1186,24 @@ module ActiveRecord
|
|
1161
1186
|
class << self
|
1162
1187
|
attr_accessor :migrations_paths
|
1163
1188
|
|
1164
|
-
def migrations_path=(path)
|
1165
|
-
ActiveSupport::Deprecation.warn \
|
1166
|
-
"`ActiveRecord::Migrator.migrations_path=` is now deprecated and will be removed in Rails 6.0. " \
|
1167
|
-
"You can set the `migrations_paths` on the `connection` instead through the `database.yml`."
|
1168
|
-
self.migrations_paths = [path]
|
1169
|
-
end
|
1170
|
-
|
1171
1189
|
# For cases where a table doesn't exist like loading from schema cache
|
1172
1190
|
def current_version
|
1173
|
-
MigrationContext.new(migrations_paths).current_version
|
1191
|
+
MigrationContext.new(migrations_paths, SchemaMigration).current_version
|
1174
1192
|
end
|
1175
1193
|
end
|
1176
1194
|
|
1177
1195
|
self.migrations_paths = ["db/migrate"]
|
1178
1196
|
|
1179
|
-
def initialize(direction, migrations, target_version = nil)
|
1197
|
+
def initialize(direction, migrations, schema_migration, target_version = nil)
|
1180
1198
|
@direction = direction
|
1181
1199
|
@target_version = target_version
|
1182
1200
|
@migrated_versions = nil
|
1183
1201
|
@migrations = migrations
|
1202
|
+
@schema_migration = schema_migration
|
1184
1203
|
|
1185
1204
|
validate(@migrations)
|
1186
1205
|
|
1187
|
-
|
1206
|
+
@schema_migration.create_table
|
1188
1207
|
ActiveRecord::InternalMetadata.create_table
|
1189
1208
|
end
|
1190
1209
|
|
@@ -1238,7 +1257,7 @@ module ActiveRecord
|
|
1238
1257
|
end
|
1239
1258
|
|
1240
1259
|
def load_migrated
|
1241
|
-
@migrated_versions = Set.new(
|
1260
|
+
@migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
|
1242
1261
|
end
|
1243
1262
|
|
1244
1263
|
private
|
@@ -1293,7 +1312,7 @@ module ActiveRecord
|
|
1293
1312
|
record_version_state_after_migrating(migration.version)
|
1294
1313
|
end
|
1295
1314
|
rescue => e
|
1296
|
-
msg = "An error has occurred, "
|
1315
|
+
msg = +"An error has occurred, "
|
1297
1316
|
msg << "this and " if use_transaction?(migration)
|
1298
1317
|
msg << "all later migrations canceled:\n\n#{e}"
|
1299
1318
|
raise StandardError, msg, e.backtrace
|
@@ -1322,10 +1341,10 @@ module ActiveRecord
|
|
1322
1341
|
def record_version_state_after_migrating(version)
|
1323
1342
|
if down?
|
1324
1343
|
migrated.delete(version)
|
1325
|
-
|
1344
|
+
@schema_migration.delete_by(version: version.to_s)
|
1326
1345
|
else
|
1327
1346
|
migrated << version
|
1328
|
-
|
1347
|
+
@schema_migration.create!(version: version.to_s)
|
1329
1348
|
end
|
1330
1349
|
end
|
1331
1350
|
|
@@ -1351,7 +1370,7 @@ module ActiveRecord
|
|
1351
1370
|
end
|
1352
1371
|
|
1353
1372
|
def use_advisory_lock?
|
1354
|
-
Base.connection.
|
1373
|
+
Base.connection.advisory_locks_enabled?
|
1355
1374
|
end
|
1356
1375
|
|
1357
1376
|
def with_advisory_lock
|
@@ -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
|
@@ -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
|
@@ -477,6 +498,7 @@ module ActiveRecord
|
|
477
498
|
def reload_schema_from_cache
|
478
499
|
@arel_table = nil
|
479
500
|
@column_names = nil
|
501
|
+
@symbol_column_to_string_name_hash = nil
|
480
502
|
@attribute_types = nil
|
481
503
|
@content_columns = nil
|
482
504
|
@default_attributes = nil
|
@@ -501,19 +523,18 @@ module ActiveRecord
|
|
501
523
|
|
502
524
|
# Computes and returns a table name according to default conventions.
|
503
525
|
def compute_table_name
|
504
|
-
|
505
|
-
if self == base
|
526
|
+
if base_class?
|
506
527
|
# Nested classes are prefixed with singular parent table name.
|
507
|
-
if
|
508
|
-
contained =
|
509
|
-
contained = contained.singularize if
|
528
|
+
if module_parent < Base && !module_parent.abstract_class?
|
529
|
+
contained = module_parent.table_name
|
530
|
+
contained = contained.singularize if module_parent.pluralize_table_names
|
510
531
|
contained += "_"
|
511
532
|
end
|
512
533
|
|
513
534
|
"#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
|
514
535
|
else
|
515
536
|
# STI subclasses always use their superclass' table.
|
516
|
-
|
537
|
+
base_class.table_name
|
517
538
|
end
|
518
539
|
end
|
519
540
|
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)
|
@@ -43,6 +43,13 @@ module ActiveRecord
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
# Returns +true+ if the class has +no_touching+ set, +false+ otherwise.
|
47
|
+
#
|
48
|
+
# Project.no_touching do
|
49
|
+
# Project.first.no_touching? # true
|
50
|
+
# Message.first.no_touching? # false
|
51
|
+
# end
|
52
|
+
#
|
46
53
|
def no_touching?
|
47
54
|
NoTouching.applied_to?(self.class)
|
48
55
|
end
|