activerecord 5.2.4.4 → 6.0.3.4
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 +777 -552
- data/MIT-LICENSE +3 -1
- data/README.rdoc +5 -3
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +10 -2
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +4 -3
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations.rb +21 -16
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +56 -19
- data/lib/active_record/associations/association_scope.rb +4 -6
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +12 -23
- data/lib/active_record/associations/collection_proxy.rb +13 -17
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -11
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +37 -28
- data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/preloader.rb +39 -32
- data/lib/active_record/associations/preloader/association.rb +38 -36
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/attribute_assignment.rb +7 -11
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -24
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -54
- data/lib/active_record/attribute_methods/serialization.rb +1 -2
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
- data/lib/active_record/attribute_methods/write.rb +17 -25
- data/lib/active_record/attributes.rb +13 -1
- data/lib/active_record/autosave_association.rb +3 -5
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +6 -21
- data/lib/active_record/coders/yaml_column.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +103 -18
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +100 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
- data/lib/active_record/connection_adapters/abstract_adapter.rb +191 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +142 -215
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +132 -16
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +135 -146
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +139 -26
- data/lib/active_record/core.rb +103 -61
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +78 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +37 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +144 -474
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +13 -6
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +11 -3
- data/lib/active_record/locking/optimistic.rb +5 -7
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +8 -27
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +104 -85
- data/lib/active_record/migration/command_recorder.rb +54 -22
- data/lib/active_record/migration/compatibility.rb +79 -52
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +33 -11
- data/lib/active_record/nested_attributes.rb +2 -4
- data/lib/active_record/no_touching.rb +9 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +232 -29
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +33 -21
- data/lib/active_record/railtie.rb +80 -43
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +199 -46
- data/lib/active_record/reflection.rb +40 -38
- data/lib/active_record/relation.rb +322 -80
- data/lib/active_record/relation/batches.rb +13 -11
- data/lib/active_record/relation/calculations.rb +54 -48
- data/lib/active_record/relation/delegation.rb +33 -49
- data/lib/active_record/relation/finder_methods.rb +23 -28
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +11 -21
- data/lib/active_record/relation/predicate_builder.rb +5 -11
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +221 -70
- data/lib/active_record/relation/spawn_methods.rb +1 -2
- data/lib/active_record/relation/where_clause.rb +14 -11
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/result.rb +30 -12
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +6 -2
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/scoping/default.rb +4 -6
- data/lib/active_record/scoping/named.rb +21 -17
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +23 -15
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +225 -0
- data/lib/active_record/timestamp.rb +39 -26
- data/lib/active_record/touch_later.rb +5 -4
- data/lib/active_record/transactions.rb +64 -73
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +0 -1
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/arel.rb +62 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +256 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/visitors/depth_first.rb +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +14 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +115 -29
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -14,45 +14,37 @@ module ActiveRecord
|
|
14
14
|
[key] if key
|
15
15
|
end
|
16
16
|
|
17
|
-
# Returns the primary key value.
|
17
|
+
# Returns the primary key column's value.
|
18
18
|
def id
|
19
|
-
|
20
|
-
primary_key = self.class.primary_key
|
21
|
-
_read_attribute(primary_key) if primary_key
|
19
|
+
_read_attribute(@primary_key)
|
22
20
|
end
|
23
21
|
|
24
|
-
# Sets the primary key value.
|
22
|
+
# Sets the primary key column's value.
|
25
23
|
def id=(value)
|
26
|
-
|
27
|
-
primary_key = self.class.primary_key
|
28
|
-
_write_attribute(primary_key, value) if primary_key
|
24
|
+
_write_attribute(@primary_key, value)
|
29
25
|
end
|
30
26
|
|
31
|
-
# Queries the primary key value.
|
27
|
+
# Queries the primary key column's value.
|
32
28
|
def id?
|
33
|
-
|
34
|
-
query_attribute(self.class.primary_key)
|
29
|
+
query_attribute(@primary_key)
|
35
30
|
end
|
36
31
|
|
37
|
-
# Returns the primary key value before type cast.
|
32
|
+
# Returns the primary key column's value before type cast.
|
38
33
|
def id_before_type_cast
|
39
|
-
|
40
|
-
read_attribute_before_type_cast(self.class.primary_key)
|
34
|
+
read_attribute_before_type_cast(@primary_key)
|
41
35
|
end
|
42
36
|
|
43
|
-
# Returns the primary key previous value.
|
37
|
+
# Returns the primary key column's previous value.
|
44
38
|
def id_was
|
45
|
-
|
46
|
-
attribute_was(self.class.primary_key)
|
39
|
+
attribute_was(@primary_key)
|
47
40
|
end
|
48
41
|
|
42
|
+
# Returns the primary key column's value from the database.
|
49
43
|
def id_in_database
|
50
|
-
|
51
|
-
attribute_in_database(self.class.primary_key)
|
44
|
+
attribute_in_database(@primary_key)
|
52
45
|
end
|
53
46
|
|
54
47
|
private
|
55
|
-
|
56
48
|
def attribute_method?(attr_name)
|
57
49
|
attr_name == "id" || super
|
58
50
|
end
|
@@ -83,7 +75,7 @@ module ActiveRecord
|
|
83
75
|
end
|
84
76
|
|
85
77
|
def reset_primary_key #:nodoc:
|
86
|
-
if
|
78
|
+
if base_class?
|
87
79
|
self.primary_key = get_primary_key(base_class.name)
|
88
80
|
else
|
89
81
|
self.primary_key = base_class.primary_key
|
@@ -121,17 +113,16 @@ module ActiveRecord
|
|
121
113
|
#
|
122
114
|
# Project.primary_key # => "foo_id"
|
123
115
|
def primary_key=(value)
|
124
|
-
@primary_key = value && value.to_s
|
116
|
+
@primary_key = value && -value.to_s
|
125
117
|
@quoted_primary_key = nil
|
126
118
|
@attributes_builder = nil
|
127
119
|
end
|
128
120
|
|
129
121
|
private
|
130
|
-
|
131
122
|
def suppress_composite_primary_key(pk)
|
132
123
|
return pk unless pk.is_a?(Array)
|
133
124
|
|
134
|
-
warn
|
125
|
+
warn <<~WARNING
|
135
126
|
WARNING: Active Record does not support composite primary key.
|
136
127
|
|
137
128
|
#{table_name} has composite primary key. Composite primary key is ignored.
|
@@ -16,8 +16,7 @@ module ActiveRecord
|
|
16
16
|
when true then true
|
17
17
|
when false, nil then false
|
18
18
|
else
|
19
|
-
|
20
|
-
if column.nil?
|
19
|
+
if !type_for_attribute(attr_name) { false }
|
21
20
|
if Numeric === value || value !~ /[^0-9]/
|
22
21
|
!value.to_i.zero?
|
23
22
|
else
|
@@ -33,7 +32,7 @@ module ActiveRecord
|
|
33
32
|
end
|
34
33
|
|
35
34
|
private
|
36
|
-
#
|
35
|
+
# Dispatch target for <tt>*?</tt> attribute methods.
|
37
36
|
def attribute?(attribute_name)
|
38
37
|
query_attribute(attribute_name)
|
39
38
|
end
|
@@ -7,43 +7,16 @@ module ActiveRecord
|
|
7
7
|
|
8
8
|
module ClassMethods # :nodoc:
|
9
9
|
private
|
10
|
-
|
11
|
-
# We want to generate the methods via module_eval rather than
|
12
|
-
# define_method, because define_method is slower on dispatch.
|
13
|
-
# Evaluating many similar methods may use more memory as the instruction
|
14
|
-
# sequences are duplicated and cached (in MRI). define_method may
|
15
|
-
# be slower on dispatch, but if you're careful about the closure
|
16
|
-
# created, then define_method will consume much less memory.
|
17
|
-
#
|
18
|
-
# But sometimes the database might return columns with
|
19
|
-
# characters that are not allowed in normal method names (like
|
20
|
-
# 'my_column(omg)'. So to work around this we first define with
|
21
|
-
# the __temp__ identifier, and then use alias method to rename
|
22
|
-
# it to what we want.
|
23
|
-
#
|
24
|
-
# We are also defining a constant to hold the frozen string of
|
25
|
-
# the attribute name. Using a constant means that we do not have
|
26
|
-
# to allocate an object on each call to the attribute method.
|
27
|
-
# Making it frozen means that it doesn't get duped when used to
|
28
|
-
# key the @attributes in read_attribute.
|
29
10
|
def define_method_attribute(name)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
40
|
-
_read_attribute(name) { |n| missing_attribute(n, caller) }
|
41
|
-
end
|
42
|
-
STR
|
43
|
-
|
44
|
-
generated_attribute_methods.module_eval do
|
45
|
-
alias_method name, temp_method
|
46
|
-
undef_method temp_method
|
11
|
+
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
12
|
+
generated_attribute_methods, name
|
13
|
+
) do |temp_method_name, attr_name_expr|
|
14
|
+
generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
15
|
+
def #{temp_method_name}
|
16
|
+
name = #{attr_name_expr}
|
17
|
+
_read_attribute(name) { |n| missing_attribute(n, caller) }
|
18
|
+
end
|
19
|
+
RUBY
|
47
20
|
end
|
48
21
|
end
|
49
22
|
end
|
@@ -52,30 +25,18 @@ module ActiveRecord
|
|
52
25
|
# it has been typecast (for example, "2004-12-12" in a date column is cast
|
53
26
|
# to a date object, like Date.new(2004, 12, 12)).
|
54
27
|
def read_attribute(attr_name, &block)
|
55
|
-
name =
|
56
|
-
|
57
|
-
else
|
58
|
-
attr_name.to_s
|
59
|
-
end
|
28
|
+
name = attr_name.to_s
|
29
|
+
name = self.class.attribute_aliases[name] || name
|
60
30
|
|
61
|
-
|
62
|
-
name = primary_key if name == "id".freeze && primary_key
|
63
|
-
sync_with_transaction_state if name == primary_key
|
31
|
+
name = @primary_key if name == "id" && @primary_key
|
64
32
|
_read_attribute(name, &block)
|
65
33
|
end
|
66
34
|
|
67
35
|
# This method exists to avoid the expensive primary_key check internally, without
|
68
36
|
# breaking compatibility with the read_attribute API
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
def _read_attribute(attr_name, &block) # :nodoc:
|
73
|
-
@attributes.fetch_value(attr_name.to_s, &block)
|
74
|
-
end
|
75
|
-
else
|
76
|
-
def _read_attribute(attr_name) # :nodoc:
|
77
|
-
@attributes.fetch_value(attr_name.to_s) { |n| yield n if block_given? }
|
78
|
-
end
|
37
|
+
def _read_attribute(attr_name, &block) # :nodoc
|
38
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
39
|
+
@attributes.fetch_value(attr_name.to_s, &block)
|
79
40
|
end
|
80
41
|
|
81
42
|
alias :attribute :_read_attribute
|
@@ -7,7 +7,7 @@ module ActiveRecord
|
|
7
7
|
|
8
8
|
class ColumnNotSerializableError < StandardError
|
9
9
|
def initialize(name, type)
|
10
|
-
super
|
10
|
+
super <<~EOS
|
11
11
|
Column `#{name}` of type #{type.class} does not support `serialize` feature.
|
12
12
|
Usually it means that you are trying to use `serialize`
|
13
13
|
on a column that already implements serialization natively.
|
@@ -79,7 +79,6 @@ module ActiveRecord
|
|
79
79
|
end
|
80
80
|
|
81
81
|
private
|
82
|
-
|
83
82
|
def type_incompatible_with_serialize?(type, class_name)
|
84
83
|
type.is_a?(ActiveRecord::Type::Json) && class_name == ::JSON ||
|
85
84
|
type.respond_to?(:type_cast_array, true) && class_name == ::Array
|
@@ -25,7 +25,6 @@ module ActiveRecord
|
|
25
25
|
end
|
26
26
|
|
27
27
|
private
|
28
|
-
|
29
28
|
def convert_time_to_time_zone(value)
|
30
29
|
return if value.nil?
|
31
30
|
|
@@ -64,7 +63,6 @@ module ActiveRecord
|
|
64
63
|
|
65
64
|
module ClassMethods # :nodoc:
|
66
65
|
private
|
67
|
-
|
68
66
|
def inherited(subclass)
|
69
67
|
super
|
70
68
|
# We need to apply this decorator here, rather than on module inclusion. The closure
|
@@ -73,7 +71,7 @@ module ActiveRecord
|
|
73
71
|
# `skip_time_zone_conversion_for_attributes` would not be picked up.
|
74
72
|
subclass.class_eval do
|
75
73
|
matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) }
|
76
|
-
decorate_matching_attribute_types(matcher,
|
74
|
+
decorate_matching_attribute_types(matcher, "_time_zone_conversion") do |type|
|
77
75
|
TimeZoneConverter.new(type)
|
78
76
|
end
|
79
77
|
end
|
@@ -11,21 +11,17 @@ module ActiveRecord
|
|
11
11
|
|
12
12
|
module ClassMethods # :nodoc:
|
13
13
|
private
|
14
|
-
|
15
14
|
def define_method_attribute=(name)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
|
27
|
-
undef_method :__temp__#{safe_name}=
|
28
|
-
STR
|
15
|
+
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
16
|
+
generated_attribute_methods, name, writer: true,
|
17
|
+
) do |temp_method_name, attr_name_expr|
|
18
|
+
generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
19
|
+
def #{temp_method_name}(value)
|
20
|
+
name = #{attr_name_expr}
|
21
|
+
_write_attribute(name, value)
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
end
|
29
25
|
end
|
30
26
|
end
|
31
27
|
|
@@ -33,33 +29,29 @@ module ActiveRecord
|
|
33
29
|
# specified +value+. Empty strings for Integer and Float columns are
|
34
30
|
# turned into +nil+.
|
35
31
|
def write_attribute(attr_name, value)
|
36
|
-
name =
|
37
|
-
|
38
|
-
else
|
39
|
-
attr_name.to_s
|
40
|
-
end
|
32
|
+
name = attr_name.to_s
|
33
|
+
name = self.class.attribute_aliases[name] || name
|
41
34
|
|
42
|
-
|
43
|
-
name = primary_key if name == "id".freeze && primary_key
|
44
|
-
sync_with_transaction_state if name == primary_key
|
35
|
+
name = @primary_key if name == "id" && @primary_key
|
45
36
|
_write_attribute(name, value)
|
46
37
|
end
|
47
38
|
|
48
39
|
# This method exists to avoid the expensive primary_key check internally, without
|
49
40
|
# breaking compatibility with the write_attribute API
|
50
41
|
def _write_attribute(attr_name, value) # :nodoc:
|
42
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
51
43
|
@attributes.write_from_user(attr_name.to_s, value)
|
52
44
|
value
|
53
45
|
end
|
54
46
|
|
55
47
|
private
|
56
48
|
def write_attribute_without_type_cast(attr_name, value)
|
57
|
-
|
58
|
-
@attributes.write_cast_value(
|
49
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
50
|
+
@attributes.write_cast_value(attr_name.to_s, value)
|
59
51
|
value
|
60
52
|
end
|
61
53
|
|
62
|
-
#
|
54
|
+
# Dispatch target for <tt>*=</tt> attribute methods.
|
63
55
|
def attribute=(attribute_name, value)
|
64
56
|
_write_attribute(attribute_name, value)
|
65
57
|
end
|
@@ -41,6 +41,9 @@ module ActiveRecord
|
|
41
41
|
# +range+ (PostgreSQL only) specifies that the type should be a range (see the
|
42
42
|
# examples below).
|
43
43
|
#
|
44
|
+
# When using a symbol for +cast_type+, extra options are forwarded to the
|
45
|
+
# constructor of the type object.
|
46
|
+
#
|
44
47
|
# ==== Examples
|
45
48
|
#
|
46
49
|
# The type detected by Active Record can be overridden.
|
@@ -112,6 +115,16 @@ module ActiveRecord
|
|
112
115
|
# my_float_range: 1.0..3.5
|
113
116
|
# }
|
114
117
|
#
|
118
|
+
# Passing options to the type constructor
|
119
|
+
#
|
120
|
+
# # app/models/my_model.rb
|
121
|
+
# class MyModel < ActiveRecord::Base
|
122
|
+
# attribute :small_int, :integer, limit: 2
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# MyModel.create(small_int: 65537)
|
126
|
+
# # => Error: 65537 is out of range for the limit of two bytes
|
127
|
+
#
|
115
128
|
# ==== Creating Custom Types
|
116
129
|
#
|
117
130
|
# Users may also define their own custom types, as long as they respond
|
@@ -242,7 +255,6 @@ module ActiveRecord
|
|
242
255
|
end
|
243
256
|
|
244
257
|
private
|
245
|
-
|
246
258
|
NO_DEFAULT_PROVIDED = Object.new # :nodoc:
|
247
259
|
private_constant :NO_DEFAULT_PROVIDED
|
248
260
|
|
@@ -147,9 +147,8 @@ module ActiveRecord
|
|
147
147
|
|
148
148
|
module ClassMethods # :nodoc:
|
149
149
|
private
|
150
|
-
|
151
150
|
def define_non_cyclic_method(name, &block)
|
152
|
-
return if
|
151
|
+
return if instance_methods(false).include?(name)
|
153
152
|
define_method(name) do |*args|
|
154
153
|
result = true; @_already_called ||= {}
|
155
154
|
# Loop prevention for validation of associations
|
@@ -267,7 +266,6 @@ module ActiveRecord
|
|
267
266
|
end
|
268
267
|
|
269
268
|
private
|
270
|
-
|
271
269
|
# Returns the record for an association collection that should be validated
|
272
270
|
# or saved. If +autosave+ is +false+ only new records will be returned,
|
273
271
|
# unless the parent is/was a new record itself.
|
@@ -363,7 +361,7 @@ module ActiveRecord
|
|
363
361
|
# Is used as a before_save callback to check while saving a collection
|
364
362
|
# association whether or not the parent was a new record before saving.
|
365
363
|
def before_save_collection_association
|
366
|
-
@new_record_before_save
|
364
|
+
@new_record_before_save ||= new_record?
|
367
365
|
end
|
368
366
|
|
369
367
|
def after_save_collection_association
|
@@ -416,7 +414,7 @@ module ActiveRecord
|
|
416
414
|
saved = record.save(validate: false)
|
417
415
|
end
|
418
416
|
|
419
|
-
raise
|
417
|
+
raise(RecordInvalid.new(association.owner)) unless saved
|
420
418
|
end
|
421
419
|
end
|
422
420
|
end
|
data/lib/active_record/base.rb
CHANGED
@@ -9,7 +9,6 @@ require "active_support/core_ext/module/attribute_accessors"
|
|
9
9
|
require "active_support/core_ext/array/extract_options"
|
10
10
|
require "active_support/core_ext/hash/deep_merge"
|
11
11
|
require "active_support/core_ext/hash/slice"
|
12
|
-
require "active_support/core_ext/hash/transform_values"
|
13
12
|
require "active_support/core_ext/string/behavior"
|
14
13
|
require "active_support/core_ext/kernel/singleton_class"
|
15
14
|
require "active_support/core_ext/module/introspection"
|
@@ -23,6 +22,7 @@ require "active_record/explain_subscriber"
|
|
23
22
|
require "active_record/relation/delegation"
|
24
23
|
require "active_record/attributes"
|
25
24
|
require "active_record/type_caster"
|
25
|
+
require "active_record/database_configurations"
|
26
26
|
|
27
27
|
module ActiveRecord #:nodoc:
|
28
28
|
# = Active Record
|
@@ -288,7 +288,7 @@ module ActiveRecord #:nodoc:
|
|
288
288
|
extend Explain
|
289
289
|
extend Enum
|
290
290
|
extend Delegation::DelegateCache
|
291
|
-
extend
|
291
|
+
extend Aggregations::ClassMethods
|
292
292
|
|
293
293
|
include Core
|
294
294
|
include Persistence
|
@@ -314,7 +314,6 @@ module ActiveRecord #:nodoc:
|
|
314
314
|
include ActiveModel::SecurePassword
|
315
315
|
include AutosaveAssociation
|
316
316
|
include NestedAttributes
|
317
|
-
include Aggregations
|
318
317
|
include Transactions
|
319
318
|
include TouchLater
|
320
319
|
include NoTouching
|
@@ -75,21 +75,7 @@ module ActiveRecord
|
|
75
75
|
# end
|
76
76
|
#
|
77
77
|
# Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
|
78
|
-
# run, both +destroy_author+ and +destroy_readers+ are called.
|
79
|
-
# where the +before_destroy+ method is overridden:
|
80
|
-
#
|
81
|
-
# class Topic < ActiveRecord::Base
|
82
|
-
# def before_destroy() destroy_author end
|
83
|
-
# end
|
84
|
-
#
|
85
|
-
# class Reply < Topic
|
86
|
-
# def before_destroy() destroy_readers end
|
87
|
-
# end
|
88
|
-
#
|
89
|
-
# In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
|
90
|
-
# So, use the callback macros when you want to ensure that a certain callback is called for the entire
|
91
|
-
# hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant
|
92
|
-
# to decide whether they want to call +super+ and trigger the inherited callbacks.
|
78
|
+
# run, both +destroy_author+ and +destroy_readers+ are called.
|
93
79
|
#
|
94
80
|
# *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
|
95
81
|
# callbacks before specifying the associations. Otherwise, you might trigger the loading of a
|
@@ -109,7 +95,7 @@ module ActiveRecord
|
|
109
95
|
#
|
110
96
|
# private
|
111
97
|
# def delete_parents
|
112
|
-
# self.class.
|
98
|
+
# self.class.delete_by(parent_id: id)
|
113
99
|
# end
|
114
100
|
# end
|
115
101
|
#
|
@@ -142,7 +128,7 @@ module ActiveRecord
|
|
142
128
|
# end
|
143
129
|
# end
|
144
130
|
#
|
145
|
-
# So you specify the object you want messaged on a given callback. When that callback is triggered, the object has
|
131
|
+
# So you specify the object you want to be messaged on a given callback. When that callback is triggered, the object has
|
146
132
|
# a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other
|
147
133
|
# initialization data such as the name of the attribute to work with:
|
148
134
|
#
|
@@ -328,7 +314,7 @@ module ActiveRecord
|
|
328
314
|
@_destroy_callback_already_called = false
|
329
315
|
end
|
330
316
|
|
331
|
-
def touch(
|
317
|
+
def touch(*, **) #:nodoc:
|
332
318
|
_run_touch_callbacks { super }
|
333
319
|
end
|
334
320
|
|
@@ -337,8 +323,7 @@ module ActiveRecord
|
|
337
323
|
end
|
338
324
|
|
339
325
|
private
|
340
|
-
|
341
|
-
def create_or_update(*)
|
326
|
+
def create_or_update(**)
|
342
327
|
_run_save_callbacks { super }
|
343
328
|
end
|
344
329
|
|
@@ -346,7 +331,7 @@ module ActiveRecord
|
|
346
331
|
_run_create_callbacks { super }
|
347
332
|
end
|
348
333
|
|
349
|
-
def _update_record
|
334
|
+
def _update_record
|
350
335
|
_run_update_callbacks { super }
|
351
336
|
end
|
352
337
|
end
|