activerecord 5.1.7 → 5.2.0.beta1
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 +5 -5
- data/CHANGELOG.md +221 -900
- data/README.rdoc +3 -3
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +10 -3
- data/lib/active_record/aggregations.rb +2 -0
- data/lib/active_record/association_relation.rb +2 -0
- data/lib/active_record/associations.rb +13 -42
- data/lib/active_record/associations/alias_tracker.rb +17 -17
- data/lib/active_record/associations/association.rb +11 -22
- data/lib/active_record/associations/association_scope.rb +32 -44
- data/lib/active_record/associations/belongs_to_association.rb +6 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
- data/lib/active_record/associations/builder/association.rb +2 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -12
- 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 +41 -33
- data/lib/active_record/associations/collection_proxy.rb +11 -14
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +4 -2
- data/lib/active_record/associations/has_many_through_association.rb +4 -2
- data/lib/active_record/associations/has_one_association.rb +3 -1
- data/lib/active_record/associations/has_one_through_association.rb +3 -1
- data/lib/active_record/associations/join_dependency.rb +22 -40
- 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/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +42 -58
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +2 -0
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +47 -7
- 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/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +5 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +6 -8
- 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 +10 -5
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +120 -28
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
- 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 +3 -1
- 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 -6
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -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.rb +2 -1
- 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_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- 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 +3 -5
- 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/quoting.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
- 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 +47 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
- 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 +19 -2
- 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 +34 -89
- 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 +27 -57
- 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 +15 -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 +40 -24
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +6 -5
- 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 +31 -20
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +2 -0
- data/lib/active_record/migration.rb +47 -21
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +20 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +29 -38
- 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 +184 -40
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +54 -1
- 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 +41 -28
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +100 -182
- data/lib/active_record/relation.rb +61 -193
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +40 -23
- data/lib/active_record/relation/delegation.rb +10 -27
- data/lib/active_record/relation/finder_methods.rb +53 -49
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +22 -19
- data/lib/active_record/relation/predicate_builder.rb +42 -79
- 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 +54 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +9 -2
- data/lib/active_record/relation/query_methods.rb +80 -69
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -0
- data/lib/active_record/relation/where_clause.rb +50 -67
- data/lib/active_record/relation/where_clause_factory.rb +4 -46
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +15 -9
- data/lib/active_record/schema.rb +3 -1
- data/lib/active_record/schema_dumper.rb +24 -23
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +15 -7
- 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 +2 -0
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +3 -1
- data/lib/active_record/tasks/database_tasks.rb +23 -12
- 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.rb +4 -1
- 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_caster.rb +2 -0
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +2 -0
- data/lib/active_record/validations.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 +36 -6
- data/lib/active_record/version.rb +2 -0
- data/lib/rails/generators/active_record.rb +3 -1
- 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.rb +2 -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/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
- metadata +25 -38
- 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.rb +0 -240
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- data/lib/active_record/attribute_set.rb +0 -113
- 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/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
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record Counter Cache
|
3
5
|
module CounterCache
|
@@ -45,17 +47,13 @@ module ActiveRecord
|
|
45
47
|
reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
|
46
48
|
counter_name = reflection.counter_cache_column
|
47
49
|
|
48
|
-
updates = { counter_name => object.send(counter_association).count(:all) }
|
49
|
-
|
50
|
-
if touch
|
51
|
-
names = touch if touch != true
|
52
|
-
updates.merge!(touch_attributes_with_time(*names))
|
53
|
-
end
|
50
|
+
updates = { counter_name.to_sym => object.send(counter_association).count(:all) }
|
51
|
+
updates.merge!(touch_updates(touch)) if touch
|
54
52
|
|
55
53
|
unscoped.where(primary_key => object.id).update_all(updates)
|
56
54
|
end
|
57
55
|
|
58
|
-
|
56
|
+
true
|
59
57
|
end
|
60
58
|
|
61
59
|
# A generic "counter updater" implementation, intended primarily to be
|
@@ -70,8 +68,8 @@ module ActiveRecord
|
|
70
68
|
# * +counters+ - A Hash containing the names of the fields
|
71
69
|
# to update as keys and the amount to update the field by as values.
|
72
70
|
# * <tt>:touch</tt> option - Touch timestamp columns when updating.
|
73
|
-
#
|
74
|
-
#
|
71
|
+
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
|
72
|
+
# touch that column or an array of symbols to touch just those ones.
|
75
73
|
#
|
76
74
|
# ==== Examples
|
77
75
|
#
|
@@ -109,8 +107,7 @@ module ActiveRecord
|
|
109
107
|
end
|
110
108
|
|
111
109
|
if touch
|
112
|
-
|
113
|
-
touch_updates = touch_attributes_with_time(*names)
|
110
|
+
touch_updates = touch_updates(touch)
|
114
111
|
updates << sanitize_sql_for_assignment(touch_updates) unless touch_updates.empty?
|
115
112
|
end
|
116
113
|
|
@@ -168,6 +165,13 @@ module ActiveRecord
|
|
168
165
|
def decrement_counter(counter_name, id, touch: nil)
|
169
166
|
update_counters(id, counter_name => -1, touch: touch)
|
170
167
|
end
|
168
|
+
|
169
|
+
private
|
170
|
+
def touch_updates(touch)
|
171
|
+
touch = timestamp_attributes_for_update_in_model if touch == true
|
172
|
+
touch_time = current_time_from_proper_timezone
|
173
|
+
Array(touch).map { |column| [ column, touch_time ] }.to_h
|
174
|
+
end
|
171
175
|
end
|
172
176
|
|
173
177
|
private
|
@@ -178,7 +182,6 @@ module ActiveRecord
|
|
178
182
|
each_counter_cached_associations do |association|
|
179
183
|
if send(association.reflection.name)
|
180
184
|
association.increment_counters
|
181
|
-
@_after_create_counter_called = true
|
182
185
|
end
|
183
186
|
end
|
184
187
|
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# This module exists because
|
3
|
-
# define callbacks, but continue to have its version of
|
4
|
-
# method of
|
4
|
+
# This module exists because ActiveRecord::AttributeMethods::Dirty needs to
|
5
|
+
# define callbacks, but continue to have its version of +save+ be the super
|
6
|
+
# method of ActiveRecord::Callbacks. This will be removed when the removal
|
5
7
|
# of deprecated code removes this need.
|
6
8
|
module DefineCallbacks
|
7
9
|
extend ActiveSupport::Concern
|
@@ -1,16 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module ActiveRecord
|
3
4
|
module DynamicMatchers #:nodoc:
|
4
|
-
def respond_to_missing?(name, include_private = false)
|
5
|
-
if self == Base
|
6
|
-
super
|
7
|
-
else
|
8
|
-
match = Method.match(self, name)
|
9
|
-
match && match.valid? || super
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
5
|
private
|
6
|
+
def respond_to_missing?(name, _)
|
7
|
+
if self == Base
|
8
|
+
super
|
9
|
+
else
|
10
|
+
match = Method.match(self, name)
|
11
|
+
match && match.valid? || super
|
12
|
+
end
|
13
|
+
end
|
14
14
|
|
15
15
|
def method_missing(name, *arguments, &block)
|
16
16
|
match = Method.match(self, name)
|
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
|
|
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)))
|
@@ -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)
|
@@ -549,9 +569,7 @@ module ActiveRecord
|
|
549
569
|
end
|
550
570
|
|
551
571
|
table_rows.each do |fixture_set_name, rows|
|
552
|
-
rows
|
553
|
-
conn.insert_fixture(row, fixture_set_name)
|
554
|
-
end
|
572
|
+
conn.insert_fixtures(rows, fixture_set_name)
|
555
573
|
end
|
556
574
|
|
557
575
|
# Cap primary key sequences to max(pk).
|
@@ -859,20 +877,12 @@ module ActiveRecord
|
|
859
877
|
|
860
878
|
included do
|
861
879
|
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
|
880
|
+
class_attribute :fixture_table_names, default: []
|
881
|
+
class_attribute :fixture_class_names, default: {}
|
882
|
+
class_attribute :use_transactional_tests, default: true
|
883
|
+
class_attribute :use_instantiated_fixtures, default: false # true, false, or :no_instances
|
884
|
+
class_attribute :pre_loaded_fixtures, default: false
|
885
|
+
class_attribute :config, default: ActiveRecord::Base
|
876
886
|
end
|
877
887
|
|
878
888
|
module ClassMethods
|
@@ -909,6 +919,8 @@ module ActiveRecord
|
|
909
919
|
|
910
920
|
define_method(accessor_name) do |*fixture_names|
|
911
921
|
force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
|
922
|
+
return_single_record = fixture_names.size == 1
|
923
|
+
fixture_names = @loaded_fixtures[fs_name].fixtures.keys if fixture_names.empty?
|
912
924
|
|
913
925
|
@fixture_cache[fs_name] ||= {}
|
914
926
|
|
@@ -923,7 +935,7 @@ module ActiveRecord
|
|
923
935
|
end
|
924
936
|
end
|
925
937
|
|
926
|
-
|
938
|
+
return_single_record ? instances.first : instances
|
927
939
|
end
|
928
940
|
private accessor_name
|
929
941
|
end
|
@@ -1053,6 +1065,10 @@ class ActiveRecord::FixtureSet::RenderContext # :nodoc:
|
|
1053
1065
|
def get_binding
|
1054
1066
|
binding()
|
1055
1067
|
end
|
1068
|
+
|
1069
|
+
def binary(path)
|
1070
|
+
%(!!binary "#{Base64.strict_encode64(File.read(path))}")
|
1071
|
+
end
|
1056
1072
|
end
|
1057
1073
|
end
|
1058
1074
|
end
|