activerecord 5.2.8.1 → 6.0.6.1
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 +938 -573
- data/MIT-LICENSE +3 -1
- data/README.rdoc +5 -3
- data/examples/performance.rb +1 -1
- 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/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +55 -19
- data/lib/active_record/associations/association_scope.rb +11 -7
- 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 +19 -23
- data/lib/active_record/associations/collection_proxy.rb +14 -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/join_association.rb +16 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +4 -4
- data/lib/active_record/associations/join_dependency.rb +47 -30
- data/lib/active_record/associations/preloader/association.rb +61 -41
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/preloader.rb +44 -33
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +21 -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/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/attribute_methods.rb +28 -100
- data/lib/active_record/attributes.rb +13 -1
- data/lib/active_record/autosave_association.rb +12 -14
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +6 -21
- data/lib/active_record/coders/yaml_column.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -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 +77 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +105 -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 +197 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -217
- 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 +139 -19
- 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/date_time.rb +8 -0
- 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/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 +25 -7
- 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 +137 -147
- 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 +108 -67
- data/lib/active_record/counter_cache.rb +8 -30
- 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/database_configurations.rb +233 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +44 -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 +14 -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/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- 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/migration.rb +104 -85
- data/lib/active_record/model_schema.rb +62 -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 -61
- 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 +51 -51
- data/lib/active_record/relation/batches.rb +13 -11
- data/lib/active_record/relation/calculations.rb +55 -49
- data/lib/active_record/relation/delegation.rb +35 -50
- 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 +12 -17
- 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/predicate_builder.rb +5 -11
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +234 -69
- 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/relation.rb +326 -81
- 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/default.rb +4 -6
- data/lib/active_record/scoping/named.rb +25 -16
- data/lib/active_record/scoping.rb +8 -9
- 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 +243 -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/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/time.rb +10 -0
- 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.rb +3 -5
- 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/associated.rb +0 -1
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record.rb +10 -2
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -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/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/nodes.rb +68 -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/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/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +62 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- 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/migration.rb +14 -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 +113 -26
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -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
|
@@ -22,16 +22,7 @@ module ActiveRecord
|
|
22
22
|
delegate :column_for_attribute, to: :class
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
def self.set_name_cache(name, value)
|
27
|
-
const_name = "ATTR_#{name}"
|
28
|
-
unless const_defined? const_name
|
29
|
-
const_set const_name, value.dup.freeze
|
30
|
-
end
|
31
|
-
end
|
32
|
-
}
|
33
|
-
|
34
|
-
BLACKLISTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
|
25
|
+
RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
|
35
26
|
|
36
27
|
class GeneratedAttributeMethods < Module #:nodoc:
|
37
28
|
include Mutex_m
|
@@ -44,7 +35,8 @@ module ActiveRecord
|
|
44
35
|
end
|
45
36
|
|
46
37
|
def initialize_generated_modules # :nodoc:
|
47
|
-
@generated_attribute_methods = GeneratedAttributeMethods.new
|
38
|
+
@generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
|
39
|
+
private_constant :GeneratedAttributeMethods
|
48
40
|
@attribute_methods_generated = false
|
49
41
|
include @generated_attribute_methods
|
50
42
|
|
@@ -59,7 +51,7 @@ module ActiveRecord
|
|
59
51
|
# attribute methods.
|
60
52
|
generated_attribute_methods.synchronize do
|
61
53
|
return false if @attribute_methods_generated
|
62
|
-
superclass.define_attribute_methods unless
|
54
|
+
superclass.define_attribute_methods unless base_class?
|
63
55
|
super(attribute_names)
|
64
56
|
@attribute_methods_generated = true
|
65
57
|
end
|
@@ -123,7 +115,7 @@ module ActiveRecord
|
|
123
115
|
# A class method is 'dangerous' if it is already (re)defined by Active Record, but
|
124
116
|
# not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
|
125
117
|
def dangerous_class_method?(method_name)
|
126
|
-
|
118
|
+
RESTRICTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
|
127
119
|
end
|
128
120
|
|
129
121
|
def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
|
@@ -167,57 +159,6 @@ module ActiveRecord
|
|
167
159
|
end
|
168
160
|
end
|
169
161
|
|
170
|
-
# Regexp whitelist. Matches the following:
|
171
|
-
# "#{table_name}.#{column_name}"
|
172
|
-
# "#{column_name}"
|
173
|
-
COLUMN_NAME_WHITELIST = /\A(?:\w+\.)?\w+\z/i
|
174
|
-
|
175
|
-
# Regexp whitelist. Matches the following:
|
176
|
-
# "#{table_name}.#{column_name}"
|
177
|
-
# "#{table_name}.#{column_name} #{direction}"
|
178
|
-
# "#{table_name}.#{column_name} #{direction} NULLS FIRST"
|
179
|
-
# "#{table_name}.#{column_name} NULLS LAST"
|
180
|
-
# "#{column_name}"
|
181
|
-
# "#{column_name} #{direction}"
|
182
|
-
# "#{column_name} #{direction} NULLS FIRST"
|
183
|
-
# "#{column_name} NULLS LAST"
|
184
|
-
COLUMN_NAME_ORDER_WHITELIST = /
|
185
|
-
\A
|
186
|
-
(?:\w+\.)?
|
187
|
-
\w+
|
188
|
-
(?:\s+asc|\s+desc)?
|
189
|
-
(?:\s+nulls\s+(?:first|last))?
|
190
|
-
\z
|
191
|
-
/ix
|
192
|
-
|
193
|
-
def enforce_raw_sql_whitelist(args, whitelist: COLUMN_NAME_WHITELIST) # :nodoc:
|
194
|
-
unexpected = args.reject do |arg|
|
195
|
-
arg.kind_of?(Arel::Node) ||
|
196
|
-
arg.is_a?(Arel::Nodes::SqlLiteral) ||
|
197
|
-
arg.is_a?(Arel::Attributes::Attribute) ||
|
198
|
-
arg.to_s.split(/\s*,\s*/).all? { |part| whitelist.match?(part) }
|
199
|
-
end
|
200
|
-
|
201
|
-
return if unexpected.none?
|
202
|
-
|
203
|
-
if allow_unsafe_raw_sql == :deprecated
|
204
|
-
ActiveSupport::Deprecation.warn(
|
205
|
-
"Dangerous query method (method whose arguments are used as raw " \
|
206
|
-
"SQL) called with non-attribute argument(s): " \
|
207
|
-
"#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
|
208
|
-
"arguments will be disallowed in Rails 6.0. This method should " \
|
209
|
-
"not be called with user-provided values, such as request " \
|
210
|
-
"parameters or model attributes. Known-safe values can be passed " \
|
211
|
-
"by wrapping them in Arel.sql()."
|
212
|
-
)
|
213
|
-
else
|
214
|
-
raise(ActiveRecord::UnknownAttributeReference,
|
215
|
-
"Query method called with non-attribute argument(s): " +
|
216
|
-
unexpected.map(&:inspect).join(", ")
|
217
|
-
)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
162
|
# Returns true if the given attribute exists, otherwise false.
|
222
163
|
#
|
223
164
|
# class Person < ActiveRecord::Base
|
@@ -270,21 +211,14 @@ module ActiveRecord
|
|
270
211
|
def respond_to?(name, include_private = false)
|
271
212
|
return false unless super
|
272
213
|
|
273
|
-
case name
|
274
|
-
when :to_partial_path
|
275
|
-
name = "to_partial_path".freeze
|
276
|
-
when :to_model
|
277
|
-
name = "to_model".freeze
|
278
|
-
else
|
279
|
-
name = name.to_s
|
280
|
-
end
|
281
|
-
|
282
214
|
# If the result is true then check for the select case.
|
283
215
|
# For queries selecting a subset of columns, return false for unselected columns.
|
284
216
|
# We check defined?(@attributes) not to issue warnings if called on objects that
|
285
217
|
# have been allocated but not yet initialized.
|
286
|
-
if defined?(@attributes)
|
287
|
-
|
218
|
+
if defined?(@attributes)
|
219
|
+
if name = self.class.symbol_column_to_string(name.to_sym)
|
220
|
+
return has_attribute?(name)
|
221
|
+
end
|
288
222
|
end
|
289
223
|
|
290
224
|
true
|
@@ -344,15 +278,8 @@ module ActiveRecord
|
|
344
278
|
# person.attribute_for_inspect(:tag_ids)
|
345
279
|
# # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
|
346
280
|
def attribute_for_inspect(attr_name)
|
347
|
-
value =
|
348
|
-
|
349
|
-
if value.is_a?(String) && value.length > 50
|
350
|
-
"#{value[0, 50]}...".inspect
|
351
|
-
elsif value.is_a?(Date) || value.is_a?(Time)
|
352
|
-
%("#{value.to_s(:db)}")
|
353
|
-
else
|
354
|
-
value.inspect
|
355
|
-
end
|
281
|
+
value = _read_attribute(attr_name)
|
282
|
+
format_for_inspect(value)
|
356
283
|
end
|
357
284
|
|
358
285
|
# Returns +true+ if the specified +attribute+ has been set by the user or by a
|
@@ -443,23 +370,12 @@ module ActiveRecord
|
|
443
370
|
@attributes.accessed
|
444
371
|
end
|
445
372
|
|
446
|
-
|
447
|
-
|
448
|
-
def attribute_method?(attr_name) # :nodoc:
|
373
|
+
private
|
374
|
+
def attribute_method?(attr_name)
|
449
375
|
# We check defined? because Syck calls respond_to? before actually calling initialize.
|
450
376
|
defined?(@attributes) && @attributes.key?(attr_name)
|
451
377
|
end
|
452
378
|
|
453
|
-
private
|
454
|
-
|
455
|
-
def attributes_with_values_for_create(attribute_names)
|
456
|
-
attributes_with_values(attributes_for_create(attribute_names))
|
457
|
-
end
|
458
|
-
|
459
|
-
def attributes_with_values_for_update(attribute_names)
|
460
|
-
attributes_with_values(attributes_for_update(attribute_names))
|
461
|
-
end
|
462
|
-
|
463
379
|
def attributes_with_values(attribute_names)
|
464
380
|
attribute_names.each_with_object({}) do |name, attrs|
|
465
381
|
attrs[name] = _read_attribute(name)
|
@@ -468,7 +384,8 @@ module ActiveRecord
|
|
468
384
|
|
469
385
|
# Filters the primary keys and readonly attributes from the attribute names.
|
470
386
|
def attributes_for_update(attribute_names)
|
471
|
-
attribute_names
|
387
|
+
attribute_names &= self.class.column_names
|
388
|
+
attribute_names.delete_if do |name|
|
472
389
|
readonly_attribute?(name)
|
473
390
|
end
|
474
391
|
end
|
@@ -476,17 +393,28 @@ module ActiveRecord
|
|
476
393
|
# Filters out the primary keys, from the attribute names, when the primary
|
477
394
|
# key is to be generated (e.g. the id attribute has no value).
|
478
395
|
def attributes_for_create(attribute_names)
|
479
|
-
attribute_names
|
396
|
+
attribute_names &= self.class.column_names
|
397
|
+
attribute_names.delete_if do |name|
|
480
398
|
pk_attribute?(name) && id.nil?
|
481
399
|
end
|
482
400
|
end
|
483
401
|
|
402
|
+
def format_for_inspect(value)
|
403
|
+
if value.is_a?(String) && value.length > 50
|
404
|
+
"#{value[0, 50]}...".inspect
|
405
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
406
|
+
%("#{value.to_s(:db)}")
|
407
|
+
else
|
408
|
+
value.inspect
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
484
412
|
def readonly_attribute?(name)
|
485
413
|
self.class.readonly_attributes.include?(name)
|
486
414
|
end
|
487
415
|
|
488
416
|
def pk_attribute?(name)
|
489
|
-
name ==
|
417
|
+
name == @primary_key
|
490
418
|
end
|
491
419
|
end
|
492
420
|
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
|
|
@@ -29,7 +29,7 @@ module ActiveRecord
|
|
29
29
|
# == Callbacks
|
30
30
|
#
|
31
31
|
# Association with autosave option defines several callbacks on your
|
32
|
-
# model (before_save, after_create, after_update). Please note that
|
32
|
+
# model (around_save, before_save, after_create, after_update). Please note that
|
33
33
|
# callbacks are executed in the order they were defined in
|
34
34
|
# model. You should avoid modifying the association content, before
|
35
35
|
# autosave callbacks are executed. Placing your callbacks after
|
@@ -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
|
@@ -181,8 +180,7 @@ module ActiveRecord
|
|
181
180
|
save_method = :"autosave_associated_records_for_#{reflection.name}"
|
182
181
|
|
183
182
|
if reflection.collection?
|
184
|
-
|
185
|
-
after_save :after_save_collection_association
|
183
|
+
around_save :around_save_collection_association
|
186
184
|
|
187
185
|
define_non_cyclic_method(save_method) { save_collection_association(reflection) }
|
188
186
|
# Doesn't use after_save as that would save associations added in after_create/after_update twice
|
@@ -267,7 +265,6 @@ module ActiveRecord
|
|
267
265
|
end
|
268
266
|
|
269
267
|
private
|
270
|
-
|
271
268
|
# Returns the record for an association collection that should be validated
|
272
269
|
# or saved. If +autosave+ is +false+ only new records will be returned,
|
273
270
|
# unless the parent is/was a new record itself.
|
@@ -360,14 +357,15 @@ module ActiveRecord
|
|
360
357
|
end
|
361
358
|
end
|
362
359
|
|
363
|
-
# Is used as
|
360
|
+
# Is used as an around_save callback to check while saving a collection
|
364
361
|
# association whether or not the parent was a new record before saving.
|
365
|
-
def
|
366
|
-
@new_record_before_save
|
367
|
-
|
362
|
+
def around_save_collection_association
|
363
|
+
previously_new_record_before_save = (@new_record_before_save ||= false)
|
364
|
+
@new_record_before_save = !previously_new_record_before_save && new_record?
|
368
365
|
|
369
|
-
|
370
|
-
|
366
|
+
yield
|
367
|
+
ensure
|
368
|
+
@new_record_before_save = previously_new_record_before_save
|
371
369
|
end
|
372
370
|
|
373
371
|
# Saves any new associated records, or all loaded autosave associations if
|
@@ -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
|
@@ -446,7 +444,7 @@ module ActiveRecord
|
|
446
444
|
unless reflection.through_reflection
|
447
445
|
record[reflection.foreign_key] = key
|
448
446
|
if inverse_reflection = reflection.inverse_of
|
449
|
-
record.association(inverse_reflection.name).
|
447
|
+
record.association(inverse_reflection.name).inversed_from(self)
|
450
448
|
end
|
451
449
|
end
|
452
450
|
|
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
|
@@ -39,21 +39,30 @@ module ActiveRecord
|
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
42
|
-
|
43
42
|
def check_arity_of_constructor
|
44
43
|
load(nil)
|
45
44
|
rescue ArgumentError
|
46
45
|
raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
|
47
46
|
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
else
|
53
|
-
if YAML.respond_to?(:unsafe_load)
|
48
|
+
if YAML.respond_to?(:unsafe_load)
|
49
|
+
def yaml_load(payload)
|
50
|
+
if ActiveRecord::Base.use_yaml_unsafe_load
|
54
51
|
YAML.unsafe_load(payload)
|
52
|
+
elsif YAML.method(:safe_load).parameters.include?([:key, :permitted_classes])
|
53
|
+
YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
|
55
54
|
else
|
55
|
+
YAML.safe_load(payload, ActiveRecord::Base.yaml_column_permitted_classes, [], true)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
def yaml_load(payload)
|
60
|
+
if ActiveRecord::Base.use_yaml_unsafe_load
|
56
61
|
YAML.load(payload)
|
62
|
+
elsif YAML.method(:safe_load).parameters.include?([:key, :permitted_classes])
|
63
|
+
YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
|
64
|
+
else
|
65
|
+
YAML.safe_load(payload, ActiveRecord::Base.yaml_column_permitted_classes, [], true)
|
57
66
|
end
|
58
67
|
end
|
59
68
|
end
|