activerecord 5.1.7 → 5.2.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 +372 -765
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -5
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +4 -2
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +16 -27
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +20 -10
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +4 -5
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +43 -35
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +3 -1
- data/lib/active_record/associations/has_many_through_association.rb +7 -18
- data/lib/active_record/associations/has_one_association.rb +4 -1
- data/lib/active_record/associations/has_one_through_association.rb +8 -7
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/join_dependency.rb +23 -43
- data/lib/active_record/associations/preloader/association.rb +45 -61
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +25 -10
- data/lib/active_record/associations.rb +31 -54
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +21 -9
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attributes.rb +6 -5
- data/lib/active_record/autosave_association.rb +8 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -10
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +11 -7
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +111 -38
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +157 -29
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -32
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +57 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -78
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +81 -96
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +111 -183
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -2
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +246 -110
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +58 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +18 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +80 -90
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +39 -60
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +17 -13
- data/lib/active_record/errors.rb +54 -21
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +67 -60
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +49 -19
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +14 -17
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +43 -0
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +40 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/model_schema.rb +16 -21
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +166 -16
- data/lib/active_record/query_cache.rb +11 -6
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +61 -3
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +46 -36
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +110 -192
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/calculations.rb +30 -8
- data/lib/active_record/relation/delegation.rb +15 -27
- data/lib/active_record/relation/finder_methods.rb +75 -78
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +51 -20
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +53 -78
- data/lib/active_record/relation/query_attribute.rb +26 -2
- data/lib/active_record/relation/query_methods.rb +89 -88
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -1
- data/lib/active_record/relation/where_clause.rb +65 -68
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +95 -208
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +129 -121
- data/lib/active_record/schema.rb +4 -2
- data/lib/active_record/schema_dumper.rb +36 -26
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +21 -7
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +3 -1
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +12 -3
- data/lib/active_record/tasks/database_tasks.rb +26 -15
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +2 -4
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +35 -5
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/version.rb +2 -0
- data/lib/active_record.rb +11 -4
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +3 -1
- metadata +24 -36
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- data/lib/active_record/attribute_set/builder.rb +0 -126
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -37
data/lib/active_record/enum.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/object/deep_dup"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -95,8 +97,7 @@ module ActiveRecord
|
|
95
97
|
|
96
98
|
module Enum
|
97
99
|
def self.extended(base) # :nodoc:
|
98
|
-
base.class_attribute(:defined_enums, instance_writer: false)
|
99
|
-
base.defined_enums = {}
|
100
|
+
base.class_attribute(:defined_enums, instance_writer: false, default: {})
|
100
101
|
end
|
101
102
|
|
102
103
|
def inherited(base) # :nodoc:
|
@@ -154,11 +155,12 @@ module ActiveRecord
|
|
154
155
|
definitions.each do |name, values|
|
155
156
|
# statuses = { }
|
156
157
|
enum_values = ActiveSupport::HashWithIndifferentAccess.new
|
157
|
-
name
|
158
|
+
name = name.to_s
|
158
159
|
|
159
160
|
# def self.statuses() statuses end
|
160
|
-
detect_enum_conflict!(name, name.
|
161
|
-
|
161
|
+
detect_enum_conflict!(name, name.pluralize, true)
|
162
|
+
singleton_class.send(:define_method, name.pluralize) { enum_values }
|
163
|
+
defined_enums[name] = enum_values
|
162
164
|
|
163
165
|
detect_enum_conflict!(name, name)
|
164
166
|
detect_enum_conflict!(name, "#{name}=")
|
@@ -170,7 +172,7 @@ module ActiveRecord
|
|
170
172
|
|
171
173
|
_enum_methods_module.module_eval do
|
172
174
|
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
|
173
|
-
pairs.each do |
|
175
|
+
pairs.each do |label, value|
|
174
176
|
if enum_prefix == true
|
175
177
|
prefix = "#{name}_"
|
176
178
|
elsif enum_prefix
|
@@ -182,23 +184,23 @@ module ActiveRecord
|
|
182
184
|
suffix = "_#{enum_suffix}"
|
183
185
|
end
|
184
186
|
|
185
|
-
value_method_name = "#{prefix}#{
|
186
|
-
enum_values[
|
187
|
+
value_method_name = "#{prefix}#{label}#{suffix}"
|
188
|
+
enum_values[label] = value
|
189
|
+
label = label.to_s
|
187
190
|
|
188
|
-
# def active?() status ==
|
191
|
+
# def active?() status == "active" end
|
189
192
|
klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
|
190
|
-
define_method("#{value_method_name}?") { self[attr] ==
|
193
|
+
define_method("#{value_method_name}?") { self[attr] == label }
|
191
194
|
|
192
|
-
# def active!() update!
|
195
|
+
# def active!() update!(status: 0) end
|
193
196
|
klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
|
194
197
|
define_method("#{value_method_name}!") { update!(attr => value) }
|
195
198
|
|
196
|
-
# scope :active, -> { where
|
199
|
+
# scope :active, -> { where(status: 0) }
|
197
200
|
klass.send(:detect_enum_conflict!, name, value_method_name, true)
|
198
201
|
klass.scope value_method_name, -> { where(attr => value) }
|
199
202
|
end
|
200
203
|
end
|
201
|
-
defined_enums[name.to_s] = enum_values
|
202
204
|
end
|
203
205
|
end
|
204
206
|
|
@@ -219,6 +221,8 @@ module ActiveRecord
|
|
219
221
|
def detect_enum_conflict!(enum_name, method_name, klass_method = false)
|
220
222
|
if klass_method && dangerous_class_method?(method_name)
|
221
223
|
raise_conflict_error(enum_name, method_name, type: "class")
|
224
|
+
elsif klass_method && method_defined_within?(method_name, Relation)
|
225
|
+
raise_conflict_error(enum_name, method_name, type: "class", source: Relation.name)
|
222
226
|
elsif !klass_method && dangerous_attribute_method?(method_name)
|
223
227
|
raise_conflict_error(enum_name, method_name)
|
224
228
|
elsif !klass_method && method_defined_within?(method_name, _enum_methods_module, Module)
|
data/lib/active_record/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record Errors
|
3
5
|
#
|
@@ -105,7 +107,7 @@ module ActiveRecord
|
|
105
107
|
class WrappedDatabaseException < StatementInvalid
|
106
108
|
end
|
107
109
|
|
108
|
-
# Raised when a record cannot be inserted because it would violate a uniqueness constraint.
|
110
|
+
# Raised when a record cannot be inserted or updated because it would violate a uniqueness constraint.
|
109
111
|
class RecordNotUnique < WrappedDatabaseException
|
110
112
|
end
|
111
113
|
|
@@ -115,27 +117,16 @@ module ActiveRecord
|
|
115
117
|
|
116
118
|
# Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
|
117
119
|
class MismatchedForeignKey < StatementInvalid
|
118
|
-
def initialize(
|
119
|
-
adapter =
|
120
|
-
message: nil,
|
121
|
-
sql: nil,
|
122
|
-
binds: nil,
|
123
|
-
table: nil,
|
124
|
-
foreign_key: nil,
|
125
|
-
target_table: nil,
|
126
|
-
primary_key: nil,
|
127
|
-
primary_key_column: nil
|
128
|
-
)
|
120
|
+
def initialize(adapter = nil, message: nil, table: nil, foreign_key: nil, target_table: nil, primary_key: nil)
|
121
|
+
@adapter = adapter
|
129
122
|
if table
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
|
135
|
-
(For example `t.#{type} :#{foreign_key}`).
|
123
|
+
msg = <<-EOM.strip_heredoc
|
124
|
+
Column `#{foreign_key}` on table `#{table}` has a type of `#{column_type(table, foreign_key)}`.
|
125
|
+
This does not match column `#{primary_key}` on `#{target_table}`, which has type `#{column_type(target_table, primary_key)}`.
|
126
|
+
To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :integer. (For example `t.integer #{foreign_key}`).
|
136
127
|
EOM
|
137
128
|
else
|
138
|
-
msg = <<-EOM
|
129
|
+
msg = <<-EOM
|
139
130
|
There is a mismatch between the foreign key and primary key column types.
|
140
131
|
Verify that the foreign key column type and the primary key of the associated table match types.
|
141
132
|
EOM
|
@@ -145,6 +136,11 @@ module ActiveRecord
|
|
145
136
|
end
|
146
137
|
super(msg)
|
147
138
|
end
|
139
|
+
|
140
|
+
private
|
141
|
+
def column_type(table, column)
|
142
|
+
@adapter.columns(table).detect { |c| c.name == column }.sql_type
|
143
|
+
end
|
148
144
|
end
|
149
145
|
|
150
146
|
# Raised when a record cannot be inserted or updated because it would violate a not null constraint.
|
@@ -173,7 +169,7 @@ module ActiveRecord
|
|
173
169
|
class NoDatabaseError < StatementInvalid
|
174
170
|
end
|
175
171
|
|
176
|
-
# Raised when
|
172
|
+
# Raised when PostgreSQL returns 'cached plan must not change result type' and
|
177
173
|
# we cannot retry gracefully (e.g. inside a transaction)
|
178
174
|
class PreparedStatementCacheExpired < StatementInvalid
|
179
175
|
end
|
@@ -319,7 +315,7 @@ module ActiveRecord
|
|
319
315
|
#
|
320
316
|
# See the following:
|
321
317
|
#
|
322
|
-
# *
|
318
|
+
# * https://www.postgresql.org/docs/current/static/transaction-iso.html
|
323
319
|
# * https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_lock_deadlock
|
324
320
|
class TransactionRollbackError < StatementInvalid
|
325
321
|
end
|
@@ -338,4 +334,41 @@ module ActiveRecord
|
|
338
334
|
# +reverse_order+ to automatically reverse.
|
339
335
|
class IrreversibleOrderError < ActiveRecordError
|
340
336
|
end
|
337
|
+
|
338
|
+
# LockWaitTimeout will be raised when lock wait timeout exceeded.
|
339
|
+
class LockWaitTimeout < StatementInvalid
|
340
|
+
end
|
341
|
+
|
342
|
+
# StatementTimeout will be raised when statement timeout exceeded.
|
343
|
+
class StatementTimeout < StatementInvalid
|
344
|
+
end
|
345
|
+
|
346
|
+
# QueryCanceled will be raised when canceling statement due to user request.
|
347
|
+
class QueryCanceled < StatementInvalid
|
348
|
+
end
|
349
|
+
|
350
|
+
# UnknownAttributeReference is raised when an unknown and potentially unsafe
|
351
|
+
# value is passed to a query method when allow_unsafe_raw_sql is set to
|
352
|
+
# :disabled. For example, passing a non column name value to a relation's
|
353
|
+
# #order method might cause this exception.
|
354
|
+
#
|
355
|
+
# When working around this exception, caution should be taken to avoid SQL
|
356
|
+
# injection vulnerabilities when passing user-provided values to query
|
357
|
+
# methods. Known-safe values can be passed to query methods by wrapping them
|
358
|
+
# in Arel.sql.
|
359
|
+
#
|
360
|
+
# For example, with allow_unsafe_raw_sql set to :disabled, the following
|
361
|
+
# code would raise this exception:
|
362
|
+
#
|
363
|
+
# Post.order("length(title)").first
|
364
|
+
#
|
365
|
+
# The desired result can be accomplished by wrapping the known-safe string
|
366
|
+
# in Arel.sql:
|
367
|
+
#
|
368
|
+
# Post.order(Arel.sql("length(title)")).first
|
369
|
+
#
|
370
|
+
# Again, such a workaround should *not* be used when passing user-provided
|
371
|
+
# values, such as request parameters or model attributes to query methods.
|
372
|
+
class UnknownAttributeReference < ActiveRecordError
|
373
|
+
end
|
341
374
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_record/explain_registry"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -16,7 +18,7 @@ module ActiveRecord
|
|
16
18
|
# Returns a formatted string ready to be logged.
|
17
19
|
def exec_explain(queries) # :nodoc:
|
18
20
|
str = queries.map do |sql, binds|
|
19
|
-
msg = "EXPLAIN for: #{sql}"
|
21
|
+
msg = "EXPLAIN for: #{sql}".dup
|
20
22
|
unless binds.empty?
|
21
23
|
msg << " "
|
22
24
|
msg << binds.map { |attr| render_bind(attr) }.inspect
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "erb"
|
2
4
|
require "yaml"
|
3
5
|
require "zlib"
|
@@ -70,13 +72,32 @@ module ActiveRecord
|
|
70
72
|
# test. To ensure consistent data, the environment deletes the fixtures before running the load.
|
71
73
|
#
|
72
74
|
# In addition to being available in the database, the fixture's data may also be accessed by
|
73
|
-
# using a special dynamic method, which has the same name as the model
|
74
|
-
#
|
75
|
+
# using a special dynamic method, which has the same name as the model.
|
76
|
+
#
|
77
|
+
# Passing in a fixture name to this dynamic method returns the fixture matching this name:
|
75
78
|
#
|
76
|
-
# test "find" do
|
79
|
+
# test "find one" do
|
77
80
|
# assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
|
78
81
|
# end
|
79
82
|
#
|
83
|
+
# Passing in multiple fixture names returns all fixtures matching these names:
|
84
|
+
#
|
85
|
+
# test "find all by name" do
|
86
|
+
# assert_equal 2, web_sites(:rubyonrails, :google).length
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# Passing in no arguments returns all fixtures:
|
90
|
+
#
|
91
|
+
# test "find all" do
|
92
|
+
# assert_equal 2, web_sites.length
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# Passing in any fixture name that does not exist will raise <tt>StandardError</tt>:
|
96
|
+
#
|
97
|
+
# test "find by name that does not exist" do
|
98
|
+
# assert_raise(StandardError) { web_sites(:reddit) }
|
99
|
+
# end
|
100
|
+
#
|
80
101
|
# Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the
|
81
102
|
# following tests:
|
82
103
|
#
|
@@ -126,7 +147,7 @@ module ActiveRecord
|
|
126
147
|
# unwanted inter-test dependencies. Methods used by multiple fixtures should be defined in a module
|
127
148
|
# that is included in ActiveRecord::FixtureSet.context_class.
|
128
149
|
#
|
129
|
-
# - define a helper method in
|
150
|
+
# - define a helper method in <tt>test_helper.rb</tt>
|
130
151
|
# module FixtureFileHelpers
|
131
152
|
# def file_sha(path)
|
132
153
|
# Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
|
@@ -148,13 +169,13 @@ module ActiveRecord
|
|
148
169
|
# self.use_transactional_tests = true
|
149
170
|
#
|
150
171
|
# test "godzilla" do
|
151
|
-
#
|
172
|
+
# assert_not_empty Foo.all
|
152
173
|
# Foo.destroy_all
|
153
|
-
#
|
174
|
+
# assert_empty Foo.all
|
154
175
|
# end
|
155
176
|
#
|
156
177
|
# test "godzilla aftermath" do
|
157
|
-
#
|
178
|
+
# assert_not_empty Foo.all
|
158
179
|
# end
|
159
180
|
# end
|
160
181
|
#
|
@@ -473,8 +494,7 @@ module ActiveRecord
|
|
473
494
|
end
|
474
495
|
end
|
475
496
|
|
476
|
-
cattr_accessor :all_loaded_fixtures
|
477
|
-
self.all_loaded_fixtures = {}
|
497
|
+
cattr_accessor :all_loaded_fixtures, default: {}
|
478
498
|
|
479
499
|
class ClassCache
|
480
500
|
def initialize(class_names, config)
|
@@ -520,49 +540,38 @@ module ActiveRecord
|
|
520
540
|
}
|
521
541
|
|
522
542
|
unless files_to_read.empty?
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
end
|
535
|
-
|
536
|
-
update_all_loaded_fixtures fixtures_map
|
537
|
-
|
538
|
-
connection.transaction(requires_new: true) do
|
539
|
-
deleted_tables = Hash.new { |h, k| h[k] = Set.new }
|
540
|
-
fixture_sets.each do |fs|
|
541
|
-
conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection
|
542
|
-
table_rows = fs.table_rows
|
543
|
+
fixtures_map = {}
|
544
|
+
|
545
|
+
fixture_sets = files_to_read.map do |fs_name|
|
546
|
+
klass = class_names[fs_name]
|
547
|
+
conn = klass ? klass.connection : connection
|
548
|
+
fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new
|
549
|
+
conn,
|
550
|
+
fs_name,
|
551
|
+
klass,
|
552
|
+
::File.join(fixtures_directory, fs_name))
|
553
|
+
end
|
543
554
|
|
544
|
-
|
545
|
-
|
546
|
-
conn.delete "DELETE FROM #{conn.quote_table_name(table)}", "Fixture Delete"
|
547
|
-
end
|
548
|
-
deleted_tables[conn] << table
|
549
|
-
end
|
555
|
+
update_all_loaded_fixtures fixtures_map
|
556
|
+
fixture_sets_by_connection = fixture_sets.group_by { |fs| fs.model_class ? fs.model_class.connection : connection }
|
550
557
|
|
551
|
-
|
552
|
-
|
553
|
-
conn.insert_fixture(row, fixture_set_name)
|
554
|
-
end
|
555
|
-
end
|
558
|
+
fixture_sets_by_connection.each do |conn, set|
|
559
|
+
table_rows_for_connection = Hash.new { |h, k| h[k] = [] }
|
556
560
|
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
end
|
561
|
+
set.each do |fs|
|
562
|
+
fs.table_rows.each do |table, rows|
|
563
|
+
table_rows_for_connection[table].unshift(*rows)
|
561
564
|
end
|
562
565
|
end
|
566
|
+
conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys)
|
563
567
|
|
564
|
-
|
568
|
+
# Cap primary key sequences to max(pk).
|
569
|
+
if conn.respond_to?(:reset_pk_sequence!)
|
570
|
+
set.each { |fs| conn.reset_pk_sequence!(fs.table_name) }
|
571
|
+
end
|
565
572
|
end
|
573
|
+
|
574
|
+
cache_fixtures(connection, fixtures_map)
|
566
575
|
end
|
567
576
|
cached_fixtures(connection, fixture_set_names)
|
568
577
|
end
|
@@ -859,20 +868,12 @@ module ActiveRecord
|
|
859
868
|
|
860
869
|
included do
|
861
870
|
class_attribute :fixture_path, instance_writer: false
|
862
|
-
class_attribute :fixture_table_names
|
863
|
-
class_attribute :fixture_class_names
|
864
|
-
class_attribute :use_transactional_tests
|
865
|
-
class_attribute :use_instantiated_fixtures # true, false, or :no_instances
|
866
|
-
class_attribute :pre_loaded_fixtures
|
867
|
-
class_attribute :config
|
868
|
-
|
869
|
-
self.fixture_table_names = []
|
870
|
-
self.use_instantiated_fixtures = false
|
871
|
-
self.pre_loaded_fixtures = false
|
872
|
-
self.config = ActiveRecord::Base
|
873
|
-
|
874
|
-
self.fixture_class_names = {}
|
875
|
-
self.use_transactional_tests = true
|
871
|
+
class_attribute :fixture_table_names, default: []
|
872
|
+
class_attribute :fixture_class_names, default: {}
|
873
|
+
class_attribute :use_transactional_tests, default: true
|
874
|
+
class_attribute :use_instantiated_fixtures, default: false # true, false, or :no_instances
|
875
|
+
class_attribute :pre_loaded_fixtures, default: false
|
876
|
+
class_attribute :config, default: ActiveRecord::Base
|
876
877
|
end
|
877
878
|
|
878
879
|
module ClassMethods
|
@@ -909,6 +910,8 @@ module ActiveRecord
|
|
909
910
|
|
910
911
|
define_method(accessor_name) do |*fixture_names|
|
911
912
|
force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
|
913
|
+
return_single_record = fixture_names.size == 1
|
914
|
+
fixture_names = @loaded_fixtures[fs_name].fixtures.keys if fixture_names.empty?
|
912
915
|
|
913
916
|
@fixture_cache[fs_name] ||= {}
|
914
917
|
|
@@ -923,7 +926,7 @@ module ActiveRecord
|
|
923
926
|
end
|
924
927
|
end
|
925
928
|
|
926
|
-
|
929
|
+
return_single_record ? instances.first : instances
|
927
930
|
end
|
928
931
|
private accessor_name
|
929
932
|
end
|
@@ -1053,6 +1056,10 @@ class ActiveRecord::FixtureSet::RenderContext # :nodoc:
|
|
1053
1056
|
def get_binding
|
1054
1057
|
binding()
|
1055
1058
|
end
|
1059
|
+
|
1060
|
+
def binary(path)
|
1061
|
+
%(!!binary "#{Base64.strict_encode64(File.read(path))}")
|
1062
|
+
end
|
1056
1063
|
end
|
1057
1064
|
end
|
1058
1065
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# Returns the version of the currently loaded Active Record as a <tt>Gem::Version</tt>
|
3
5
|
def self.gem_version
|
@@ -6,8 +8,8 @@ module ActiveRecord
|
|
6
8
|
|
7
9
|
module VERSION
|
8
10
|
MAJOR = 5
|
9
|
-
MINOR =
|
10
|
-
TINY =
|
11
|
+
MINOR = 2
|
12
|
+
TINY = 0
|
11
13
|
PRE = nil
|
12
14
|
|
13
15
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/indifferent_access"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -30,7 +32,7 @@ module ActiveRecord
|
|
30
32
|
# for differentiating between them or reloading the right type with find.
|
31
33
|
#
|
32
34
|
# Note, all the attributes for all the cases are kept in the same table. Read more:
|
33
|
-
#
|
35
|
+
# https://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
|
34
36
|
#
|
35
37
|
module Inheritance
|
36
38
|
extend ActiveSupport::Concern
|
@@ -38,22 +40,20 @@ module ActiveRecord
|
|
38
40
|
included do
|
39
41
|
# Determines whether to store the full constant name including namespace when using STI.
|
40
42
|
# This is true, by default.
|
41
|
-
class_attribute :store_full_sti_class, instance_writer: false
|
42
|
-
self.store_full_sti_class = true
|
43
|
+
class_attribute :store_full_sti_class, instance_writer: false, default: true
|
43
44
|
end
|
44
45
|
|
45
46
|
module ClassMethods
|
46
47
|
# Determines if one of the attributes passed in is the inheritance column,
|
47
48
|
# and if the inheritance column is attr accessible, it initializes an
|
48
49
|
# instance of the given subclass instead of the base class.
|
49
|
-
def new(
|
50
|
+
def new(attributes = nil, &block)
|
50
51
|
if abstract_class? || self == Base
|
51
52
|
raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
|
52
53
|
end
|
53
54
|
|
54
|
-
attrs = args.first
|
55
55
|
if has_attribute?(inheritance_column)
|
56
|
-
subclass = subclass_from_attributes(
|
56
|
+
subclass = subclass_from_attributes(attributes)
|
57
57
|
|
58
58
|
if subclass.nil? && base_class == self
|
59
59
|
subclass = subclass_from_attributes(column_defaults)
|
@@ -61,7 +61,7 @@ module ActiveRecord
|
|
61
61
|
end
|
62
62
|
|
63
63
|
if subclass && subclass != self
|
64
|
-
subclass.new(
|
64
|
+
subclass.new(attributes, &block)
|
65
65
|
else
|
66
66
|
super
|
67
67
|
end
|
@@ -104,21 +104,47 @@ module ActiveRecord
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
# Set this to true if this is an abstract class (see
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
107
|
+
# Set this to +true+ if this is an abstract class (see
|
108
|
+
# <tt>abstract_class?</tt>).
|
109
|
+
# If you are using inheritance with Active Record and don't want a class
|
110
|
+
# to be considered as part of the STI hierarchy, you must set this to
|
111
|
+
# true.
|
112
|
+
# +ApplicationRecord+, for example, is generated as an abstract class.
|
113
|
+
#
|
114
|
+
# Consider the following default behaviour:
|
115
|
+
#
|
116
|
+
# Shape = Class.new(ActiveRecord::Base)
|
117
|
+
# Polygon = Class.new(Shape)
|
118
|
+
# Square = Class.new(Polygon)
|
119
|
+
#
|
120
|
+
# Shape.table_name # => "shapes"
|
121
|
+
# Polygon.table_name # => "shapes"
|
122
|
+
# Square.table_name # => "shapes"
|
123
|
+
# Shape.create! # => #<Shape id: 1, type: nil>
|
124
|
+
# Polygon.create! # => #<Polygon id: 2, type: "Polygon">
|
125
|
+
# Square.create! # => #<Square id: 3, type: "Square">
|
126
|
+
#
|
127
|
+
# However, when using <tt>abstract_class</tt>, +Shape+ is omitted from
|
128
|
+
# the hierarchy:
|
111
129
|
#
|
112
|
-
# class
|
130
|
+
# class Shape < ActiveRecord::Base
|
113
131
|
# self.abstract_class = true
|
114
132
|
# end
|
115
|
-
#
|
116
|
-
#
|
117
|
-
# end
|
118
|
-
#
|
133
|
+
# Polygon = Class.new(Shape)
|
134
|
+
# Square = Class.new(Polygon)
|
119
135
|
#
|
120
|
-
#
|
136
|
+
# Shape.table_name # => nil
|
137
|
+
# Polygon.table_name # => "polygons"
|
138
|
+
# Square.table_name # => "polygons"
|
139
|
+
# Shape.create! # => NotImplementedError: Shape is an abstract class and cannot be instantiated.
|
140
|
+
# Polygon.create! # => #<Polygon id: 1, type: nil>
|
141
|
+
# Square.create! # => #<Square id: 2, type: "Square">
|
121
142
|
#
|
143
|
+
# Note that in the above example, to disallow the creation of a plain
|
144
|
+
# +Polygon+, you should use <tt>validates :type, presence: true</tt>,
|
145
|
+
# instead of setting it as an abstract class. This way, +Polygon+ will
|
146
|
+
# stay in the hierarchy, and Active Record will continue to correctly
|
147
|
+
# derive the table name.
|
122
148
|
attr_accessor :abstract_class
|
123
149
|
|
124
150
|
# Returns whether this class is an abstract class or not.
|
@@ -130,6 +156,10 @@ module ActiveRecord
|
|
130
156
|
store_full_sti_class ? name : name.demodulize
|
131
157
|
end
|
132
158
|
|
159
|
+
def polymorphic_name
|
160
|
+
base_class.name
|
161
|
+
end
|
162
|
+
|
133
163
|
def inherited(subclass)
|
134
164
|
subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
|
135
165
|
super
|
@@ -217,7 +247,7 @@ module ActiveRecord
|
|
217
247
|
def subclass_from_attributes(attrs)
|
218
248
|
attrs = attrs.to_h if attrs.respond_to?(:permitted?)
|
219
249
|
if attrs.is_a?(Hash)
|
220
|
-
subclass_name = attrs
|
250
|
+
subclass_name = attrs[inheritance_column] || attrs[inheritance_column.to_sym]
|
221
251
|
|
222
252
|
if subclass_name.present?
|
223
253
|
find_sti_class(subclass_name)
|
@@ -246,7 +276,7 @@ module ActiveRecord
|
|
246
276
|
def ensure_proper_type
|
247
277
|
klass = self.class
|
248
278
|
if klass.finder_needs_type_condition?
|
249
|
-
|
279
|
+
_write_attribute(klass.inheritance_column, klass.sti_name)
|
250
280
|
end
|
251
281
|
end
|
252
282
|
end
|