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
|
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,18 @@ 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
|
+
end
|
15
20
|
|
16
21
|
class V5_0 < V5_1
|
17
22
|
module TableDefinition
|
23
|
+
def primary_key(name, type = :primary_key, **options)
|
24
|
+
type = :integer if type == :primary_key
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
18
28
|
def references(*args, **options)
|
19
29
|
super(*args, type: :integer, **options)
|
20
30
|
end
|
@@ -34,7 +44,7 @@ module ActiveRecord
|
|
34
44
|
end
|
35
45
|
end
|
36
46
|
|
37
|
-
# Since 5.1
|
47
|
+
# Since 5.1 PostgreSQL adapter uses bigserial type for primary
|
38
48
|
# keys by default and MySQL uses bigint. This compat layer makes old migrations utilize
|
39
49
|
# serial/int type instead -- the way it used to work before 5.1.
|
40
50
|
unless options.key?(:id)
|
@@ -72,6 +82,14 @@ module ActiveRecord
|
|
72
82
|
end
|
73
83
|
end
|
74
84
|
|
85
|
+
def add_column(table_name, column_name, type, options = {})
|
86
|
+
if type == :primary_key
|
87
|
+
type = :integer
|
88
|
+
options[:primary_key] = true
|
89
|
+
end
|
90
|
+
super
|
91
|
+
end
|
92
|
+
|
75
93
|
def add_reference(table_name, ref_name, **options)
|
76
94
|
super(table_name, ref_name, type: :integer, **options)
|
77
95
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "monitor"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -84,6 +86,19 @@ module ActiveRecord
|
|
84
86
|
#
|
85
87
|
# Sets the name of the internal metadata table.
|
86
88
|
|
89
|
+
##
|
90
|
+
# :singleton-method: protected_environments
|
91
|
+
# :call-seq: protected_environments
|
92
|
+
#
|
93
|
+
# The array of names of environments where destructive actions should be prohibited. By default,
|
94
|
+
# the value is <tt>["production"]</tt>.
|
95
|
+
|
96
|
+
##
|
97
|
+
# :singleton-method: protected_environments=
|
98
|
+
# :call-seq: protected_environments=(environments)
|
99
|
+
#
|
100
|
+
# Sets an array of names of environments where destructive actions should be prohibited.
|
101
|
+
|
87
102
|
##
|
88
103
|
# :singleton-method: pluralize_table_names
|
89
104
|
# :call-seq: pluralize_table_names
|
@@ -103,22 +118,13 @@ module ActiveRecord
|
|
103
118
|
included do
|
104
119
|
mattr_accessor :primary_key_prefix_type, instance_writer: false
|
105
120
|
|
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"
|
121
|
+
class_attribute :table_name_prefix, instance_writer: false, default: ""
|
122
|
+
class_attribute :table_name_suffix, instance_writer: false, default: ""
|
123
|
+
class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
|
124
|
+
class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
|
125
|
+
class_attribute :protected_environments, instance_accessor: false, default: [ "production" ]
|
126
|
+
class_attribute :pluralize_table_names, instance_writer: false, default: true
|
114
127
|
|
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
|
120
|
-
|
121
|
-
self.protected_environments = ["production"]
|
122
128
|
self.inheritance_column = "type"
|
123
129
|
self.ignored_columns = [].freeze
|
124
130
|
|
@@ -232,21 +238,6 @@ module ActiveRecord
|
|
232
238
|
(parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
|
233
239
|
end
|
234
240
|
|
235
|
-
# The array of names of environments where destructive actions should be prohibited. By default,
|
236
|
-
# the value is <tt>["production"]</tt>.
|
237
|
-
def protected_environments
|
238
|
-
if defined?(@protected_environments)
|
239
|
-
@protected_environments
|
240
|
-
else
|
241
|
-
superclass.protected_environments
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
# Sets an array of names of environments where destructive actions should be prohibited.
|
246
|
-
def protected_environments=(environments)
|
247
|
-
@protected_environments = environments.map(&:to_s)
|
248
|
-
end
|
249
|
-
|
250
241
|
# Defines the name of the table column which will store the class name on single-table
|
251
242
|
# inheritance situations.
|
252
243
|
#
|
@@ -332,11 +323,11 @@ module ActiveRecord
|
|
332
323
|
end
|
333
324
|
|
334
325
|
def attributes_builder # :nodoc:
|
335
|
-
|
336
|
-
|
337
|
-
|
326
|
+
@attributes_builder ||= ActiveModel::AttributeSet::Builder.new(attribute_types, primary_key) do |name|
|
327
|
+
unless columns_hash.key?(name)
|
328
|
+
_default_attributes[name].dup
|
329
|
+
end
|
338
330
|
end
|
339
|
-
@attributes_builder
|
340
331
|
end
|
341
332
|
|
342
333
|
def columns_hash # :nodoc:
|
@@ -355,7 +346,7 @@ module ActiveRecord
|
|
355
346
|
end
|
356
347
|
|
357
348
|
def yaml_encoder # :nodoc:
|
358
|
-
@yaml_encoder ||= AttributeSet::YAMLEncoder.new(attribute_types)
|
349
|
+
@yaml_encoder ||= ActiveModel::AttributeSet::YAMLEncoder.new(attribute_types)
|
359
350
|
end
|
360
351
|
|
361
352
|
# Returns the type of the attribute with the given name, after applying
|
@@ -381,11 +372,11 @@ module ActiveRecord
|
|
381
372
|
# default values when instantiating the Active Record object for this table.
|
382
373
|
def column_defaults
|
383
374
|
load_schema
|
384
|
-
_default_attributes.
|
375
|
+
@column_defaults ||= _default_attributes.to_hash
|
385
376
|
end
|
386
377
|
|
387
378
|
def _default_attributes # :nodoc:
|
388
|
-
@default_attributes ||= AttributeSet.new({})
|
379
|
+
@default_attributes ||= ActiveModel::AttributeSet.new({})
|
389
380
|
end
|
390
381
|
|
391
382
|
# Returns an array of column names as strings.
|
@@ -480,12 +471,12 @@ module ActiveRecord
|
|
480
471
|
end
|
481
472
|
|
482
473
|
def reload_schema_from_cache
|
483
|
-
@arel_engine = nil
|
484
474
|
@arel_table = nil
|
485
475
|
@column_names = nil
|
486
476
|
@attribute_types = nil
|
487
477
|
@content_columns = nil
|
488
478
|
@default_attributes = nil
|
479
|
+
@column_defaults = nil
|
489
480
|
@inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
|
490
481
|
@attributes_builder = nil
|
491
482
|
@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,132 @@ 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.with_index { |one_id, idx| update(one_id, attributes[idx]) }.compact
|
103
|
+
elsif id == :all
|
104
|
+
all.each { |record| record.update(attributes) }
|
105
|
+
else
|
106
|
+
if ActiveRecord::Base === id
|
107
|
+
raise ArgumentError,
|
108
|
+
"You are passing an instance of ActiveRecord::Base to `update`. " \
|
109
|
+
"Please pass the id of the object by calling `.id`."
|
110
|
+
end
|
111
|
+
object = find(id)
|
112
|
+
object.update(attributes)
|
113
|
+
object
|
114
|
+
end
|
115
|
+
rescue RecordNotFound
|
116
|
+
end
|
117
|
+
|
118
|
+
# Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
|
119
|
+
# therefore all callbacks and filters are fired off before the object is deleted. This method is
|
120
|
+
# less efficient than #delete but allows cleanup methods and other actions to be run.
|
121
|
+
#
|
122
|
+
# This essentially finds the object (or multiple objects) with the given id, creates a new object
|
123
|
+
# from the attributes, and then calls destroy on it.
|
124
|
+
#
|
125
|
+
# ==== Parameters
|
126
|
+
#
|
127
|
+
# * +id+ - This should be the id or an array of ids to be destroyed.
|
128
|
+
#
|
129
|
+
# ==== Examples
|
130
|
+
#
|
131
|
+
# # Destroy a single object
|
132
|
+
# Todo.destroy(1)
|
133
|
+
#
|
134
|
+
# # Destroy multiple objects
|
135
|
+
# todos = [1,2,3]
|
136
|
+
# Todo.destroy(todos)
|
137
|
+
def destroy(id)
|
138
|
+
if id.is_a?(Array)
|
139
|
+
id.map { |one_id| destroy(one_id) }.compact
|
140
|
+
else
|
141
|
+
find(id).destroy
|
142
|
+
end
|
143
|
+
rescue RecordNotFound
|
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
|
+
arel_primary_key = arel_attribute(primary_key)
|
173
|
+
primary_key_value = values[arel_primary_key]
|
174
|
+
|
175
|
+
if !primary_key_value && prefetch_primary_key?
|
176
|
+
primary_key_value = next_sequence_value
|
177
|
+
values[arel_primary_key] = primary_key_value
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
if values.empty?
|
182
|
+
im = arel_table.compile_insert(connection.empty_insert_statement_value)
|
183
|
+
im.into arel_table
|
184
|
+
else
|
185
|
+
im = arel_table.compile_insert(_substitute_values(values))
|
186
|
+
end
|
187
|
+
|
188
|
+
connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
|
189
|
+
end
|
190
|
+
|
191
|
+
def _update_record(values, id, id_was) # :nodoc:
|
192
|
+
bind = predicate_builder.build_bind_attribute(primary_key, id_was || id)
|
193
|
+
um = arel_table.where(
|
194
|
+
arel_attribute(primary_key).eq(bind)
|
195
|
+
).compile_update(_substitute_values(values), primary_key)
|
196
|
+
|
197
|
+
connection.update(um, "#{self} Update")
|
198
|
+
end
|
199
|
+
|
72
200
|
private
|
73
201
|
# Called by +instantiate+ to decide which class to use for a new
|
74
202
|
# record instance.
|
@@ -78,6 +206,13 @@ module ActiveRecord
|
|
78
206
|
def discriminate_class_for_record(record)
|
79
207
|
self
|
80
208
|
end
|
209
|
+
|
210
|
+
def _substitute_values(values)
|
211
|
+
values.map do |attr, value|
|
212
|
+
bind = predicate_builder.build_bind_attribute(attr.name, value)
|
213
|
+
[attr, bind]
|
214
|
+
end
|
215
|
+
end
|
81
216
|
end
|
82
217
|
|
83
218
|
# Returns true if this object hasn't been saved yet -- that is, a record
|
@@ -175,7 +310,7 @@ module ActiveRecord
|
|
175
310
|
# callbacks or any <tt>:dependent</tt> association
|
176
311
|
# options, use <tt>#destroy</tt>.
|
177
312
|
def delete
|
178
|
-
|
313
|
+
_relation_for_itself.delete_all if persisted?
|
179
314
|
@destroyed = true
|
180
315
|
freeze
|
181
316
|
end
|
@@ -226,8 +361,7 @@ module ActiveRecord
|
|
226
361
|
def becomes(klass)
|
227
362
|
became = klass.new
|
228
363
|
became.instance_variable_set("@attributes", @attributes)
|
229
|
-
became.instance_variable_set("@
|
230
|
-
became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
|
364
|
+
became.instance_variable_set("@mutations_from_database", @mutations_from_database) if defined?(@mutations_from_database)
|
231
365
|
became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
|
232
366
|
became.instance_variable_set("@new_record", new_record?)
|
233
367
|
became.instance_variable_set("@destroyed", destroyed?)
|
@@ -268,7 +402,11 @@ module ActiveRecord
|
|
268
402
|
verify_readonly_attribute(name)
|
269
403
|
public_send("#{name}=", value)
|
270
404
|
|
271
|
-
|
405
|
+
if has_changes_to_save?
|
406
|
+
save(validate: false)
|
407
|
+
else
|
408
|
+
true
|
409
|
+
end
|
272
410
|
end
|
273
411
|
|
274
412
|
# Updates the attributes of the model from the passed-in hash and saves the
|
@@ -327,10 +465,10 @@ module ActiveRecord
|
|
327
465
|
verify_readonly_attribute(key.to_s)
|
328
466
|
end
|
329
467
|
|
330
|
-
updated_count =
|
468
|
+
updated_count = _relation_for_itself.update_all(attributes)
|
331
469
|
|
332
470
|
attributes.each do |k, v|
|
333
|
-
|
471
|
+
write_attribute_without_type_cast(k, v)
|
334
472
|
end
|
335
473
|
|
336
474
|
updated_count == 1
|
@@ -348,7 +486,7 @@ module ActiveRecord
|
|
348
486
|
# Wrapper around #increment that writes the update to the database.
|
349
487
|
# Only +attribute+ is updated; the record itself is not saved.
|
350
488
|
# This means that any other modified attributes will still be dirty.
|
351
|
-
# Validations and callbacks are skipped. Supports the
|
489
|
+
# Validations and callbacks are skipped. Supports the +touch+ option from
|
352
490
|
# +update_counters+, see that for more.
|
353
491
|
# Returns +self+.
|
354
492
|
def increment!(attribute, by = 1, touch: nil)
|
@@ -369,7 +507,7 @@ module ActiveRecord
|
|
369
507
|
# Wrapper around #decrement that writes the update to the database.
|
370
508
|
# Only +attribute+ is updated; the record itself is not saved.
|
371
509
|
# This means that any other modified attributes will still be dirty.
|
372
|
-
# Validations and callbacks are skipped. Supports the
|
510
|
+
# Validations and callbacks are skipped. Supports the +touch+ option from
|
373
511
|
# +update_counters+, see that for more.
|
374
512
|
# Returns +self+.
|
375
513
|
def decrement!(attribute, by = 1, touch: nil)
|
@@ -506,12 +644,35 @@ module ActiveRecord
|
|
506
644
|
MSG
|
507
645
|
end
|
508
646
|
|
509
|
-
|
510
|
-
|
647
|
+
time ||= current_time_from_proper_timezone
|
648
|
+
attributes = timestamp_attributes_for_update_in_model
|
649
|
+
attributes.concat(names)
|
650
|
+
|
651
|
+
unless attributes.empty?
|
652
|
+
changes = {}
|
511
653
|
|
512
|
-
|
513
|
-
|
514
|
-
|
654
|
+
attributes.each do |column|
|
655
|
+
column = column.to_s
|
656
|
+
changes[column] = write_attribute(column, time)
|
657
|
+
end
|
658
|
+
|
659
|
+
scope = _relation_for_itself
|
660
|
+
|
661
|
+
if locking_enabled?
|
662
|
+
locking_column = self.class.locking_column
|
663
|
+
scope = scope.where(locking_column => read_attribute_before_type_cast(locking_column))
|
664
|
+
changes[locking_column] = increment_lock
|
665
|
+
end
|
666
|
+
|
667
|
+
clear_attribute_changes(changes.keys)
|
668
|
+
result = scope.update_all(changes) == 1
|
669
|
+
|
670
|
+
if !result && locking_enabled?
|
671
|
+
raise ActiveRecord::StaleObjectError.new(self, "touch")
|
672
|
+
end
|
673
|
+
|
674
|
+
@_trigger_update_callback = result
|
675
|
+
result
|
515
676
|
else
|
516
677
|
true
|
517
678
|
end
|
@@ -528,25 +689,11 @@ module ActiveRecord
|
|
528
689
|
end
|
529
690
|
|
530
691
|
def relation_for_destroy
|
531
|
-
|
692
|
+
_relation_for_itself
|
532
693
|
end
|
533
694
|
|
534
|
-
def
|
535
|
-
|
536
|
-
|
537
|
-
attribute_names.each do |attr_name|
|
538
|
-
write_attribute(attr_name, time)
|
539
|
-
clear_attribute_change(attr_name)
|
540
|
-
end
|
541
|
-
|
542
|
-
_update_row(attribute_names, "touch")
|
543
|
-
end
|
544
|
-
|
545
|
-
def _update_row(attribute_names, attempted_action = "update")
|
546
|
-
self.class.unscoped._update_record(
|
547
|
-
arel_attributes_with_values(attribute_names),
|
548
|
-
self.class.primary_key => id_in_database
|
549
|
-
)
|
695
|
+
def _relation_for_itself
|
696
|
+
self.class.unscoped.where(self.class.primary_key => id)
|
550
697
|
end
|
551
698
|
|
552
699
|
def create_or_update(*args, &block)
|
@@ -558,29 +705,26 @@ module ActiveRecord
|
|
558
705
|
# Updates the associated record with values matching those of the instance attributes.
|
559
706
|
# Returns the number of affected rows.
|
560
707
|
def _update_record(attribute_names = self.attribute_names)
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
if attribute_names.empty?
|
565
|
-
affected_rows = 0
|
708
|
+
attributes_values = arel_attributes_with_values_for_update(attribute_names)
|
709
|
+
if attributes_values.empty?
|
710
|
+
rows_affected = 0
|
566
711
|
@_trigger_update_callback = true
|
567
712
|
else
|
568
|
-
|
569
|
-
@_trigger_update_callback =
|
713
|
+
rows_affected = self.class._update_record(attributes_values, id, id_in_database)
|
714
|
+
@_trigger_update_callback = rows_affected > 0
|
570
715
|
end
|
571
716
|
|
572
717
|
yield(self) if block_given?
|
573
718
|
|
574
|
-
|
719
|
+
rows_affected
|
575
720
|
end
|
576
721
|
|
577
722
|
# Creates a record with values matching those of the instance attributes
|
578
723
|
# and returns its id.
|
579
724
|
def _create_record(attribute_names = self.attribute_names)
|
580
|
-
attribute_names &= self.class.column_names
|
581
725
|
attributes_values = arel_attributes_with_values_for_create(attribute_names)
|
582
726
|
|
583
|
-
new_id = self.class.
|
727
|
+
new_id = self.class._insert_record(attributes_values)
|
584
728
|
self.id ||= new_id if self.class.primary_key
|
585
729
|
|
586
730
|
@new_record = false
|