activerecord 5.1.7 → 5.2.4.3
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 +556 -685
- 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.rb +11 -4
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +7 -5
- data/lib/active_record/associations.rb +40 -63
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +41 -37
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +27 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +12 -4
- data/lib/active_record/associations/builder/collection_association.rb +3 -3
- 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 +59 -47
- data/lib/active_record/associations/collection_proxy.rb +20 -49
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +12 -1
- data/lib/active_record/associations/has_many_through_association.rb +36 -30
- data/lib/active_record/associations/has_one_association.rb +12 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency.rb +48 -93
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
- data/lib/active_record/associations/preloader.rb +18 -38
- 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/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +26 -11
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +30 -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 +9 -3
- 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 +6 -5
- data/lib/active_record/autosave_association.rb +35 -19
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -6
- 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 +12 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +139 -41
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -31
- 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 +64 -6
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
- 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 +13 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -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.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -0
- 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 -2
- 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 +18 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -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 +233 -111
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -73
- 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 +22 -0
- 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 +75 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +81 -94
- 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 +41 -61
- data/lib/active_record/counter_cache.rb +10 -3
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +18 -13
- data/lib/active_record/errors.rb +42 -3
- 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 +5 -3
- 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.rb +189 -139
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +47 -9
- data/lib/active_record/migration/join_table.rb +2 -0
- 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 +167 -16
- data/lib/active_record/query_cache.rb +6 -8
- data/lib/active_record/querying.rb +4 -2
- data/lib/active_record/railtie.rb +62 -6
- 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 +108 -194
- data/lib/active_record/relation.rb +120 -214
- 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 +45 -19
- data/lib/active_record/relation/delegation.rb +45 -27
- data/lib/active_record/relation/finder_methods.rb +75 -76
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +53 -23
- data/lib/active_record/relation/predicate_builder.rb +60 -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 +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/query_attribute.rb +28 -2
- data/lib/active_record/relation/query_methods.rb +128 -99
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +4 -2
- 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/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.rb +9 -8
- data/lib/active_record/scoping/default.rb +8 -9
- data/lib/active_record/scoping/named.rb +23 -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 +23 -13
- 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 +25 -14
- 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 +6 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +33 -28
- 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 -0
- 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 +3 -1
- 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 +35 -5
- 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 +23 -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.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
|
class Migration
|
3
5
|
# <tt>ActiveRecord::Migration::CommandRecorder</tt> records commands done during
|
@@ -92,10 +94,6 @@ module ActiveRecord
|
|
92
94
|
send(method, args, &block)
|
93
95
|
end
|
94
96
|
|
95
|
-
def respond_to_missing?(*args) # :nodoc:
|
96
|
-
super || delegate.respond_to?(*args)
|
97
|
-
end
|
98
|
-
|
99
97
|
ReversibleAndIrreversibleMethods.each do |method|
|
100
98
|
class_eval <<-EOV, __FILE__, __LINE__ + 1
|
101
99
|
def #{method}(*args, &block) # def create_table(*args, &block)
|
@@ -112,7 +110,7 @@ module ActiveRecord
|
|
112
110
|
|
113
111
|
private
|
114
112
|
|
115
|
-
module StraightReversions
|
113
|
+
module StraightReversions # :nodoc:
|
116
114
|
private
|
117
115
|
{ transaction: :transaction,
|
118
116
|
execute_block: :execute_block,
|
@@ -163,8 +161,8 @@ module ActiveRecord
|
|
163
161
|
table, columns, options = *args
|
164
162
|
options ||= {}
|
165
163
|
|
166
|
-
|
167
|
-
options_hash =
|
164
|
+
options_hash = options.slice(:name, :algorithm)
|
165
|
+
options_hash[:column] = columns if !options_hash[:name]
|
168
166
|
|
169
167
|
[:remove_index, [table, options_hash]]
|
170
168
|
end
|
@@ -225,10 +223,14 @@ module ActiveRecord
|
|
225
223
|
[:add_foreign_key, reversed_args]
|
226
224
|
end
|
227
225
|
|
226
|
+
def respond_to_missing?(method, _)
|
227
|
+
super || delegate.respond_to?(method)
|
228
|
+
end
|
229
|
+
|
228
230
|
# Forwards any missing method call to the \target.
|
229
231
|
def method_missing(method, *args, &block)
|
230
|
-
if
|
231
|
-
|
232
|
+
if delegate.respond_to?(method)
|
233
|
+
delegate.public_send(method, *args, &block)
|
232
234
|
else
|
233
235
|
super
|
234
236
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class Migration
|
3
5
|
module Compatibility # :nodoc: all
|
@@ -11,10 +13,36 @@ module ActiveRecord
|
|
11
13
|
const_get(name)
|
12
14
|
end
|
13
15
|
|
14
|
-
|
16
|
+
V5_2 = Current
|
17
|
+
|
18
|
+
class V5_1 < V5_2
|
19
|
+
def change_column(table_name, column_name, type, options = {})
|
20
|
+
if connection.adapter_name == "PostgreSQL"
|
21
|
+
super(table_name, column_name, type, options.except(:default, :null, :comment))
|
22
|
+
connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
|
23
|
+
connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
|
24
|
+
connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
|
25
|
+
else
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_table(table_name, options = {})
|
31
|
+
if connection.adapter_name == "Mysql2"
|
32
|
+
super(table_name, options: "ENGINE=InnoDB", **options)
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
15
38
|
|
16
39
|
class V5_0 < V5_1
|
17
40
|
module TableDefinition
|
41
|
+
def primary_key(name, type = :primary_key, **options)
|
42
|
+
type = :integer if type == :primary_key
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
18
46
|
def references(*args, **options)
|
19
47
|
super(*args, type: :integer, **options)
|
20
48
|
end
|
@@ -22,19 +50,19 @@ module ActiveRecord
|
|
22
50
|
end
|
23
51
|
|
24
52
|
def create_table(table_name, options = {})
|
25
|
-
if adapter_name == "PostgreSQL"
|
53
|
+
if connection.adapter_name == "PostgreSQL"
|
26
54
|
if options[:id] == :uuid && !options.key?(:default)
|
27
55
|
options[:default] = "uuid_generate_v4()"
|
28
56
|
end
|
29
57
|
end
|
30
58
|
|
31
|
-
unless adapter_name == "Mysql2" && options[:id] == :bigint
|
59
|
+
unless connection.adapter_name == "Mysql2" && options[:id] == :bigint
|
32
60
|
if [:integer, :bigint].include?(options[:id]) && !options.key?(:default)
|
33
61
|
options[:default] = nil
|
34
62
|
end
|
35
63
|
end
|
36
64
|
|
37
|
-
# Since 5.1
|
65
|
+
# Since 5.1 PostgreSQL adapter uses bigserial type for primary
|
38
66
|
# keys by default and MySQL uses bigint. This compat layer makes old migrations utilize
|
39
67
|
# serial/int type instead -- the way it used to work before 5.1.
|
40
68
|
unless options.key?(:id)
|
@@ -72,6 +100,14 @@ module ActiveRecord
|
|
72
100
|
end
|
73
101
|
end
|
74
102
|
|
103
|
+
def add_column(table_name, column_name, type, options = {})
|
104
|
+
if type == :primary_key
|
105
|
+
type = :integer
|
106
|
+
options[:primary_key] = true
|
107
|
+
end
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
75
111
|
def add_reference(table_name, ref_name, **options)
|
76
112
|
super(table_name, ref_name, type: :integer, **options)
|
77
113
|
end
|
@@ -137,7 +173,7 @@ module ActiveRecord
|
|
137
173
|
if options[:name].present?
|
138
174
|
options[:name].to_s
|
139
175
|
else
|
140
|
-
index_name(table_name, column: column_names)
|
176
|
+
connection.index_name(table_name, column: column_names)
|
141
177
|
end
|
142
178
|
super
|
143
179
|
end
|
@@ -157,15 +193,17 @@ module ActiveRecord
|
|
157
193
|
end
|
158
194
|
|
159
195
|
def index_name_for_remove(table_name, options = {})
|
160
|
-
index_name = index_name(table_name, options)
|
196
|
+
index_name = connection.index_name(table_name, options)
|
161
197
|
|
162
|
-
unless index_name_exists?(table_name, index_name)
|
198
|
+
unless connection.index_name_exists?(table_name, index_name)
|
163
199
|
if options.is_a?(Hash) && options.has_key?(:name)
|
164
200
|
options_without_column = options.dup
|
165
201
|
options_without_column.delete :column
|
166
|
-
index_name_without_column = index_name(table_name, options_without_column)
|
202
|
+
index_name_without_column = connection.index_name(table_name, options_without_column)
|
167
203
|
|
168
|
-
|
204
|
+
if connection.index_name_exists?(table_name, index_name_without_column)
|
205
|
+
return index_name_without_column
|
206
|
+
end
|
169
207
|
end
|
170
208
|
|
171
209
|
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "monitor"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -103,20 +105,11 @@ module ActiveRecord
|
|
103
105
|
included do
|
104
106
|
mattr_accessor :primary_key_prefix_type, instance_writer: false
|
105
107
|
|
106
|
-
class_attribute :table_name_prefix, instance_writer: false
|
107
|
-
|
108
|
-
|
109
|
-
class_attribute :
|
110
|
-
|
111
|
-
|
112
|
-
class_attribute :schema_migrations_table_name, instance_accessor: false
|
113
|
-
self.schema_migrations_table_name = "schema_migrations"
|
114
|
-
|
115
|
-
class_attribute :internal_metadata_table_name, instance_accessor: false
|
116
|
-
self.internal_metadata_table_name = "ar_internal_metadata"
|
117
|
-
|
118
|
-
class_attribute :pluralize_table_names, instance_writer: false
|
119
|
-
self.pluralize_table_names = true
|
108
|
+
class_attribute :table_name_prefix, instance_writer: false, default: ""
|
109
|
+
class_attribute :table_name_suffix, instance_writer: false, default: ""
|
110
|
+
class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
|
111
|
+
class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
|
112
|
+
class_attribute :pluralize_table_names, instance_writer: false, default: true
|
120
113
|
|
121
114
|
self.protected_environments = ["production"]
|
122
115
|
self.inheritance_column = "type"
|
@@ -334,7 +327,7 @@ module ActiveRecord
|
|
334
327
|
def attributes_builder # :nodoc:
|
335
328
|
unless defined?(@attributes_builder) && @attributes_builder
|
336
329
|
defaults = _default_attributes.except(*(column_names - [primary_key]))
|
337
|
-
@attributes_builder = AttributeSet::Builder.new(attribute_types, defaults)
|
330
|
+
@attributes_builder = ActiveModel::AttributeSet::Builder.new(attribute_types, defaults)
|
338
331
|
end
|
339
332
|
@attributes_builder
|
340
333
|
end
|
@@ -355,7 +348,7 @@ module ActiveRecord
|
|
355
348
|
end
|
356
349
|
|
357
350
|
def yaml_encoder # :nodoc:
|
358
|
-
@yaml_encoder ||= AttributeSet::YAMLEncoder.new(attribute_types)
|
351
|
+
@yaml_encoder ||= ActiveModel::AttributeSet::YAMLEncoder.new(attribute_types)
|
359
352
|
end
|
360
353
|
|
361
354
|
# Returns the type of the attribute with the given name, after applying
|
@@ -368,8 +361,9 @@ module ActiveRecord
|
|
368
361
|
# it).
|
369
362
|
#
|
370
363
|
# +attr_name+ The name of the attribute to retrieve the type for. Must be
|
371
|
-
# a string
|
364
|
+
# a string or a symbol.
|
372
365
|
def type_for_attribute(attr_name, &block)
|
366
|
+
attr_name = attr_name.to_s
|
373
367
|
if block
|
374
368
|
attribute_types.fetch(attr_name, &block)
|
375
369
|
else
|
@@ -381,11 +375,12 @@ module ActiveRecord
|
|
381
375
|
# default values when instantiating the Active Record object for this table.
|
382
376
|
def column_defaults
|
383
377
|
load_schema
|
384
|
-
_default_attributes.deep_dup.to_hash
|
378
|
+
@column_defaults ||= _default_attributes.deep_dup.to_hash
|
385
379
|
end
|
386
380
|
|
387
381
|
def _default_attributes # :nodoc:
|
388
|
-
|
382
|
+
load_schema
|
383
|
+
@default_attributes ||= ActiveModel::AttributeSet.new({})
|
389
384
|
end
|
390
385
|
|
391
386
|
# Returns an array of column names as strings.
|
@@ -432,7 +427,7 @@ module ActiveRecord
|
|
432
427
|
# end
|
433
428
|
def reset_column_information
|
434
429
|
connection.clear_cache!
|
435
|
-
undefine_attribute_methods
|
430
|
+
([self] + descendants).each(&:undefine_attribute_methods)
|
436
431
|
connection.schema_cache.clear_data_source_cache!(table_name)
|
437
432
|
|
438
433
|
reload_schema_from_cache
|
@@ -480,12 +475,12 @@ module ActiveRecord
|
|
480
475
|
end
|
481
476
|
|
482
477
|
def reload_schema_from_cache
|
483
|
-
@arel_engine = nil
|
484
478
|
@arel_table = nil
|
485
479
|
@column_names = nil
|
486
480
|
@attribute_types = nil
|
487
481
|
@content_columns = nil
|
488
482
|
@default_attributes = nil
|
483
|
+
@column_defaults = nil
|
489
484
|
@inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
|
490
485
|
@attributes_builder = nil
|
491
486
|
@columns = nil
|
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/except"
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
2
5
|
require "active_support/core_ext/object/try"
|
3
6
|
require "active_support/core_ext/hash/indifferent_access"
|
4
7
|
|
@@ -10,8 +13,7 @@ module ActiveRecord
|
|
10
13
|
extend ActiveSupport::Concern
|
11
14
|
|
12
15
|
included do
|
13
|
-
class_attribute :nested_attributes_options, instance_writer: false
|
14
|
-
self.nested_attributes_options = {}
|
16
|
+
class_attribute :nested_attributes_options, instance_writer: false, default: {}
|
15
17
|
end
|
16
18
|
|
17
19
|
# = Active Record Nested Attributes
|
@@ -61,6 +63,18 @@ module ActiveRecord
|
|
61
63
|
# member.update params[:member]
|
62
64
|
# member.avatar.icon # => 'sad'
|
63
65
|
#
|
66
|
+
# If you want to update the current avatar without providing the id, you must add <tt>:update_only</tt> option.
|
67
|
+
#
|
68
|
+
# class Member < ActiveRecord::Base
|
69
|
+
# has_one :avatar
|
70
|
+
# accepts_nested_attributes_for :avatar, update_only: true
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# params = { member: { avatar_attributes: { icon: 'sad' } } }
|
74
|
+
# member.update params[:member]
|
75
|
+
# member.avatar.id # => 2
|
76
|
+
# member.avatar.icon # => 'sad'
|
77
|
+
#
|
64
78
|
# By default you will only be able to set and update attributes on the
|
65
79
|
# associated model. If you want to destroy the associated model through the
|
66
80
|
# attributes hash, you have to enable it first using the
|
@@ -354,9 +368,7 @@ module ActiveRecord
|
|
354
368
|
# associations are just regular associations.
|
355
369
|
def generate_association_writer(association_name, type)
|
356
370
|
generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
|
357
|
-
|
358
|
-
remove_method(:#{association_name}_attributes=)
|
359
|
-
end
|
371
|
+
silence_redefinition_of_method :#{association_name}_attributes=
|
360
372
|
def #{association_name}_attributes=(attributes)
|
361
373
|
assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
|
362
374
|
end
|
@@ -458,7 +470,7 @@ module ActiveRecord
|
|
458
470
|
end
|
459
471
|
|
460
472
|
unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
|
461
|
-
raise ArgumentError, "Hash or Array expected
|
473
|
+
raise ArgumentError, "Hash or Array expected for attribute `#{association_name}`, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
|
462
474
|
end
|
463
475
|
|
464
476
|
check_record_limit!(options[:limit], attributes_collection)
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record No Touching
|
3
5
|
module NoTouching
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
6
8
|
module ClassMethods
|
7
|
-
# Lets you selectively disable calls to
|
9
|
+
# Lets you selectively disable calls to +touch+ for the
|
8
10
|
# duration of a block.
|
9
11
|
#
|
10
12
|
# ==== Examples
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record \Persistence
|
3
5
|
module Persistence
|
@@ -69,6 +71,142 @@ module ActiveRecord
|
|
69
71
|
klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block)
|
70
72
|
end
|
71
73
|
|
74
|
+
# Updates an object (or multiple objects) and saves it to the database, if validations pass.
|
75
|
+
# The resulting object is returned whether the object was saved successfully to the database or not.
|
76
|
+
#
|
77
|
+
# ==== Parameters
|
78
|
+
#
|
79
|
+
# * +id+ - This should be the id or an array of ids to be updated.
|
80
|
+
# * +attributes+ - This should be a hash of attributes or an array of hashes.
|
81
|
+
#
|
82
|
+
# ==== Examples
|
83
|
+
#
|
84
|
+
# # Updates one record
|
85
|
+
# Person.update(15, user_name: "Samuel", group: "expert")
|
86
|
+
#
|
87
|
+
# # Updates multiple records
|
88
|
+
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
|
89
|
+
# Person.update(people.keys, people.values)
|
90
|
+
#
|
91
|
+
# # Updates multiple records from the result of a relation
|
92
|
+
# people = Person.where(group: "expert")
|
93
|
+
# people.update(group: "masters")
|
94
|
+
#
|
95
|
+
# Note: Updating a large number of records will run an UPDATE
|
96
|
+
# query for each record, which may cause a performance issue.
|
97
|
+
# When running callbacks is not needed for each record update,
|
98
|
+
# it is preferred to use {update_all}[rdoc-ref:Relation#update_all]
|
99
|
+
# for updating all records in a single query.
|
100
|
+
def update(id = :all, attributes)
|
101
|
+
if id.is_a?(Array)
|
102
|
+
id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
|
103
|
+
object.update(attributes[idx])
|
104
|
+
}
|
105
|
+
elsif id == :all
|
106
|
+
all.each { |record| record.update(attributes) }
|
107
|
+
else
|
108
|
+
if ActiveRecord::Base === id
|
109
|
+
raise ArgumentError,
|
110
|
+
"You are passing an instance of ActiveRecord::Base to `update`. " \
|
111
|
+
"Please pass the id of the object by calling `.id`."
|
112
|
+
end
|
113
|
+
object = find(id)
|
114
|
+
object.update(attributes)
|
115
|
+
object
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
|
120
|
+
# therefore all callbacks and filters are fired off before the object is deleted. This method is
|
121
|
+
# less efficient than #delete but allows cleanup methods and other actions to be run.
|
122
|
+
#
|
123
|
+
# This essentially finds the object (or multiple objects) with the given id, creates a new object
|
124
|
+
# from the attributes, and then calls destroy on it.
|
125
|
+
#
|
126
|
+
# ==== Parameters
|
127
|
+
#
|
128
|
+
# * +id+ - This should be the id or an array of ids to be destroyed.
|
129
|
+
#
|
130
|
+
# ==== Examples
|
131
|
+
#
|
132
|
+
# # Destroy a single object
|
133
|
+
# Todo.destroy(1)
|
134
|
+
#
|
135
|
+
# # Destroy multiple objects
|
136
|
+
# todos = [1,2,3]
|
137
|
+
# Todo.destroy(todos)
|
138
|
+
def destroy(id)
|
139
|
+
if id.is_a?(Array)
|
140
|
+
find(id).each(&:destroy)
|
141
|
+
else
|
142
|
+
find(id).destroy
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Deletes the row with a primary key matching the +id+ argument, using a
|
147
|
+
# SQL +DELETE+ statement, and returns the number of rows deleted. Active
|
148
|
+
# Record objects are not instantiated, so the object's callbacks are not
|
149
|
+
# executed, including any <tt>:dependent</tt> association options.
|
150
|
+
#
|
151
|
+
# You can delete multiple rows at once by passing an Array of <tt>id</tt>s.
|
152
|
+
#
|
153
|
+
# Note: Although it is often much faster than the alternative, #destroy,
|
154
|
+
# skipping callbacks might bypass business logic in your application
|
155
|
+
# that ensures referential integrity or performs other essential jobs.
|
156
|
+
#
|
157
|
+
# ==== Examples
|
158
|
+
#
|
159
|
+
# # Delete a single row
|
160
|
+
# Todo.delete(1)
|
161
|
+
#
|
162
|
+
# # Delete multiple rows
|
163
|
+
# Todo.delete([2,3,4])
|
164
|
+
def delete(id_or_array)
|
165
|
+
where(primary_key => id_or_array).delete_all
|
166
|
+
end
|
167
|
+
|
168
|
+
def _insert_record(values) # :nodoc:
|
169
|
+
primary_key_value = nil
|
170
|
+
|
171
|
+
if primary_key && Hash === values
|
172
|
+
primary_key_value = values[primary_key]
|
173
|
+
|
174
|
+
if !primary_key_value && prefetch_primary_key?
|
175
|
+
primary_key_value = next_sequence_value
|
176
|
+
values[primary_key] = primary_key_value
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
if values.empty?
|
181
|
+
im = arel_table.compile_insert(connection.empty_insert_statement_value)
|
182
|
+
im.into arel_table
|
183
|
+
else
|
184
|
+
im = arel_table.compile_insert(_substitute_values(values))
|
185
|
+
end
|
186
|
+
|
187
|
+
connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
|
188
|
+
end
|
189
|
+
|
190
|
+
def _update_record(values, constraints) # :nodoc:
|
191
|
+
constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) }
|
192
|
+
|
193
|
+
um = arel_table.where(
|
194
|
+
constraints.reduce(&:and)
|
195
|
+
).compile_update(_substitute_values(values), primary_key)
|
196
|
+
|
197
|
+
connection.update(um, "#{self} Update")
|
198
|
+
end
|
199
|
+
|
200
|
+
def _delete_record(constraints) # :nodoc:
|
201
|
+
constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) }
|
202
|
+
|
203
|
+
dm = Arel::DeleteManager.new
|
204
|
+
dm.from(arel_table)
|
205
|
+
dm.wheres = constraints
|
206
|
+
|
207
|
+
connection.delete(dm, "#{self} Destroy")
|
208
|
+
end
|
209
|
+
|
72
210
|
private
|
73
211
|
# Called by +instantiate+ to decide which class to use for a new
|
74
212
|
# record instance.
|
@@ -78,6 +216,14 @@ module ActiveRecord
|
|
78
216
|
def discriminate_class_for_record(record)
|
79
217
|
self
|
80
218
|
end
|
219
|
+
|
220
|
+
def _substitute_values(values)
|
221
|
+
values.map do |name, value|
|
222
|
+
attr = arel_attribute(name)
|
223
|
+
bind = predicate_builder.build_bind_attribute(name, value)
|
224
|
+
[attr, bind]
|
225
|
+
end
|
226
|
+
end
|
81
227
|
end
|
82
228
|
|
83
229
|
# Returns true if this object hasn't been saved yet -- that is, a record
|
@@ -175,7 +321,7 @@ module ActiveRecord
|
|
175
321
|
# callbacks or any <tt>:dependent</tt> association
|
176
322
|
# options, use <tt>#destroy</tt>.
|
177
323
|
def delete
|
178
|
-
|
324
|
+
_delete_row if persisted?
|
179
325
|
@destroyed = true
|
180
326
|
freeze
|
181
327
|
end
|
@@ -224,9 +370,9 @@ module ActiveRecord
|
|
224
370
|
# Any change to the attributes on either instance will affect both instances.
|
225
371
|
# If you want to change the sti column as well, use #becomes! instead.
|
226
372
|
def becomes(klass)
|
227
|
-
became = klass.
|
373
|
+
became = klass.allocate
|
374
|
+
became.send(:initialize)
|
228
375
|
became.instance_variable_set("@attributes", @attributes)
|
229
|
-
became.instance_variable_set("@mutation_tracker", @mutation_tracker ||= nil)
|
230
376
|
became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
|
231
377
|
became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
|
232
378
|
became.instance_variable_set("@new_record", new_record?)
|
@@ -327,13 +473,17 @@ module ActiveRecord
|
|
327
473
|
verify_readonly_attribute(key.to_s)
|
328
474
|
end
|
329
475
|
|
330
|
-
|
331
|
-
|
476
|
+
id_in_database = self.id_in_database
|
332
477
|
attributes.each do |k, v|
|
333
|
-
|
478
|
+
write_attribute_without_type_cast(k, v)
|
334
479
|
end
|
335
480
|
|
336
|
-
|
481
|
+
affected_rows = self.class._update_record(
|
482
|
+
attributes,
|
483
|
+
self.class.primary_key => id_in_database
|
484
|
+
)
|
485
|
+
|
486
|
+
affected_rows == 1
|
337
487
|
end
|
338
488
|
|
339
489
|
# Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
|
@@ -348,7 +498,7 @@ module ActiveRecord
|
|
348
498
|
# Wrapper around #increment that writes the update to the database.
|
349
499
|
# Only +attribute+ is updated; the record itself is not saved.
|
350
500
|
# This means that any other modified attributes will still be dirty.
|
351
|
-
# Validations and callbacks are skipped. Supports the
|
501
|
+
# Validations and callbacks are skipped. Supports the +touch+ option from
|
352
502
|
# +update_counters+, see that for more.
|
353
503
|
# Returns +self+.
|
354
504
|
def increment!(attribute, by = 1, touch: nil)
|
@@ -369,7 +519,7 @@ module ActiveRecord
|
|
369
519
|
# Wrapper around #decrement that writes the update to the database.
|
370
520
|
# Only +attribute+ is updated; the record itself is not saved.
|
371
521
|
# This means that any other modified attributes will still be dirty.
|
372
|
-
# Validations and callbacks are skipped. Supports the
|
522
|
+
# Validations and callbacks are skipped. Supports the +touch+ option from
|
373
523
|
# +update_counters+, see that for more.
|
374
524
|
# Returns +self+.
|
375
525
|
def decrement!(attribute, by = 1, touch: nil)
|
@@ -524,11 +674,11 @@ module ActiveRecord
|
|
524
674
|
end
|
525
675
|
|
526
676
|
def destroy_row
|
527
|
-
|
677
|
+
_delete_row
|
528
678
|
end
|
529
679
|
|
530
|
-
def
|
531
|
-
self.class.
|
680
|
+
def _delete_row
|
681
|
+
self.class._delete_record(self.class.primary_key => id_in_database)
|
532
682
|
end
|
533
683
|
|
534
684
|
def _touch_row(attribute_names, time)
|
@@ -543,14 +693,15 @@ module ActiveRecord
|
|
543
693
|
end
|
544
694
|
|
545
695
|
def _update_row(attribute_names, attempted_action = "update")
|
546
|
-
self.class.
|
547
|
-
|
696
|
+
self.class._update_record(
|
697
|
+
attributes_with_values(attribute_names),
|
548
698
|
self.class.primary_key => id_in_database
|
549
699
|
)
|
550
700
|
end
|
551
701
|
|
552
702
|
def create_or_update(*args, &block)
|
553
703
|
_raise_readonly_record_error if readonly?
|
704
|
+
return false if destroyed?
|
554
705
|
result = new_record? ? _create_record(&block) : _update_record(*args, &block)
|
555
706
|
result != false
|
556
707
|
end
|
@@ -578,9 +729,9 @@ module ActiveRecord
|
|
578
729
|
# and returns its id.
|
579
730
|
def _create_record(attribute_names = self.attribute_names)
|
580
731
|
attribute_names &= self.class.column_names
|
581
|
-
attributes_values =
|
732
|
+
attributes_values = attributes_with_values_for_create(attribute_names)
|
582
733
|
|
583
|
-
new_id = self.class.
|
734
|
+
new_id = self.class._insert_record(attributes_values)
|
584
735
|
self.id ||= new_id if self.class.primary_key
|
585
736
|
|
586
737
|
@new_record = false
|