activerecord 5.0.6 → 6.0.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 +5 -5
- data/CHANGELOG.md +638 -2023
- data/MIT-LICENSE +3 -1
- data/README.rdoc +8 -6
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record/aggregations.rb +249 -246
- data/lib/active_record/association_relation.rb +24 -13
- data/lib/active_record/associations/alias_tracker.rb +24 -33
- data/lib/active_record/associations/association.rb +119 -56
- data/lib/active_record/associations/association_scope.rb +94 -94
- data/lib/active_record/associations/belongs_to_association.rb +58 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +18 -25
- data/lib/active_record/associations/builder/belongs_to.rb +43 -54
- data/lib/active_record/associations/builder/collection_association.rb +7 -18
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
- data/lib/active_record/associations/builder/has_many.rb +4 -0
- data/lib/active_record/associations/builder/has_one.rb +37 -1
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +80 -252
- data/lib/active_record/associations/collection_proxy.rb +158 -121
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -29
- data/lib/active_record/associations/has_many_through_association.rb +58 -44
- data/lib/active_record/associations/has_one_association.rb +59 -54
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +134 -176
- data/lib/active_record/associations/preloader/association.rb +84 -125
- data/lib/active_record/associations/preloader/through_association.rb +82 -75
- data/lib/active_record/associations/preloader.rb +90 -102
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +26 -14
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/attribute_assignment.rb +54 -60
- data/lib/active_record/attribute_decorators.rb +38 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +86 -91
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +21 -49
- data/lib/active_record/attribute_methods/serialization.rb +30 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
- data/lib/active_record/attribute_methods/write.rb +35 -33
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attributes.rb +38 -24
- data/lib/active_record/autosave_association.rb +53 -32
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +63 -33
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -11
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
- data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- 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 +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
- 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/oid.rb +24 -21
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
- data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
- data/lib/active_record/connection_handling.rb +159 -40
- data/lib/active_record/core.rb +202 -162
- data/lib/active_record/counter_cache.rb +57 -28
- 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 +79 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -86
- data/lib/active_record/enum.rb +60 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -3
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +13 -8
- 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 +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +195 -502
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +151 -97
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +15 -18
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +78 -87
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +48 -29
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +143 -97
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +367 -300
- data/lib/active_record/model_schema.rb +145 -139
- data/lib/active_record/nested_attributes.rb +214 -201
- data/lib/active_record/no_touching.rb +10 -1
- data/lib/active_record/null_relation.rb +13 -34
- data/lib/active_record/persistence.rb +442 -72
- data/lib/active_record/query_cache.rb +15 -14
- data/lib/active_record/querying.rb +36 -23
- data/lib/active_record/railtie.rb +128 -36
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +309 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +211 -249
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/batches.rb +99 -52
- data/lib/active_record/relation/calculations.rb +211 -172
- data/lib/active_record/relation/delegation.rb +67 -65
- data/lib/active_record/relation/finder_methods.rb +208 -247
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +78 -61
- data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +86 -104
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +458 -329
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -7
- data/lib/active_record/relation/where_clause.rb +111 -95
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/relation.rb +429 -318
- data/lib/active_record/result.rb +69 -39
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +83 -99
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +71 -69
- data/lib/active_record/schema_migration.rb +15 -5
- data/lib/active_record/scoping/default.rb +93 -95
- data/lib/active_record/scoping/named.rb +45 -25
- data/lib/active_record/scoping.rb +20 -19
- data/lib/active_record/secure_token.rb +4 -2
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +63 -28
- data/lib/active_record/store.rb +121 -41
- data/lib/active_record/suppressor.rb +4 -1
- data/lib/active_record/table_metadata.rb +26 -20
- data/lib/active_record/tasks/database_tasks.rb +276 -85
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
- data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +70 -35
- data/lib/active_record/touch_later.rb +7 -4
- data/lib/active_record/transactions.rb +133 -149
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +44 -45
- 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 +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- 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 +16 -8
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +2 -1
- data/lib/active_record/type/type_map.rb +13 -15
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +23 -17
- data/lib/active_record/type_caster/connection.rb +17 -12
- data/lib/active_record/type_caster/map.rb +5 -4
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +3 -1
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +29 -42
- data/lib/active_record/validations.rb +7 -4
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -22
- 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 +257 -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 +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +58 -0
- 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/migration_generator.rb +37 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
- data/lib/rails/generators/active_record/migration.rb +17 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +133 -50
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- 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 -20
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set/builder.rb +0 -130
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
- 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/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,55 +1,50 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_model/forbidden_attributes_protection"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
module AttributeAssignment
|
5
|
-
extend ActiveSupport::Concern
|
6
7
|
include ActiveModel::AttributeAssignment
|
7
8
|
|
8
|
-
# Alias for ActiveModel::AttributeAssignment#assign_attributes. See ActiveModel::AttributeAssignment.
|
9
|
-
def attributes=(attributes)
|
10
|
-
assign_attributes(attributes)
|
11
|
-
end
|
12
|
-
|
13
9
|
private
|
14
10
|
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
def _assign_attributes(attributes)
|
12
|
+
multi_parameter_attributes = {}
|
13
|
+
nested_parameter_attributes = {}
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
attributes.each do |k, v|
|
16
|
+
if k.include?("(")
|
17
|
+
multi_parameter_attributes[k] = attributes.delete(k)
|
18
|
+
elsif v.is_a?(Hash)
|
19
|
+
nested_parameter_attributes[k] = attributes.delete(k)
|
20
|
+
end
|
24
21
|
end
|
25
|
-
|
26
|
-
super(attributes)
|
22
|
+
super(attributes)
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
|
25
|
+
assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
|
26
|
+
end
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
# Assign any deferred nested attributes after the base attributes have been set.
|
29
|
+
def assign_nested_parameter_attributes(pairs)
|
30
|
+
pairs.each { |k, v| _assign_attribute(k, v) }
|
31
|
+
end
|
36
32
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
33
|
+
# Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
|
34
|
+
# by calling new on the column type or aggregation type (through composed_of) object with these parameters.
|
35
|
+
# So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
|
36
|
+
# written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
|
37
|
+
# parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
|
38
|
+
# f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
|
39
|
+
def assign_multiparameter_attributes(pairs)
|
40
|
+
execute_callstack_for_multiparameter_attributes(
|
41
|
+
extract_callstack_for_multiparameter_attributes(pairs)
|
42
|
+
)
|
43
|
+
end
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
begin
|
45
|
+
def execute_callstack_for_multiparameter_attributes(callstack)
|
46
|
+
errors = []
|
47
|
+
callstack.each do |name, values_with_empty_parameters|
|
53
48
|
if values_with_empty_parameters.each_value.all?(&:nil?)
|
54
49
|
values = nil
|
55
50
|
else
|
@@ -59,33 +54,32 @@ module ActiveRecord
|
|
59
54
|
rescue => ex
|
60
55
|
errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name)
|
61
56
|
end
|
57
|
+
unless errors.empty?
|
58
|
+
error_descriptions = errors.map(&:message).join(",")
|
59
|
+
raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
|
60
|
+
end
|
62
61
|
end
|
63
|
-
unless errors.empty?
|
64
|
-
error_descriptions = errors.map(&:message).join(",")
|
65
|
-
raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
|
66
|
-
end
|
67
|
-
end
|
68
62
|
|
69
|
-
|
70
|
-
|
63
|
+
def extract_callstack_for_multiparameter_attributes(pairs)
|
64
|
+
attributes = {}
|
71
65
|
|
72
|
-
|
73
|
-
|
74
|
-
|
66
|
+
pairs.each do |(multiparameter_name, value)|
|
67
|
+
attribute_name = multiparameter_name.split("(").first
|
68
|
+
attributes[attribute_name] ||= {}
|
75
69
|
|
76
|
-
|
77
|
-
|
78
|
-
|
70
|
+
parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
|
71
|
+
attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
|
72
|
+
end
|
79
73
|
|
80
|
-
|
81
|
-
|
74
|
+
attributes
|
75
|
+
end
|
82
76
|
|
83
|
-
|
84
|
-
|
85
|
-
|
77
|
+
def type_cast_attribute_value(multiparameter_name, value)
|
78
|
+
multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
|
79
|
+
end
|
86
80
|
|
87
|
-
|
88
|
-
|
89
|
-
|
81
|
+
def find_parameter_position(multiparameter_name)
|
82
|
+
multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
|
83
|
+
end
|
90
84
|
end
|
91
85
|
end
|
@@ -1,19 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeDecorators # :nodoc:
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
included do
|
6
|
-
class_attribute :attribute_type_decorations, instance_accessor: false # :internal:
|
7
|
-
self.attribute_type_decorations = TypeDecorator.new
|
8
|
+
class_attribute :attribute_type_decorations, instance_accessor: false, default: TypeDecorator.new # :internal:
|
8
9
|
end
|
9
10
|
|
10
11
|
module ClassMethods # :nodoc:
|
12
|
+
# This method is an internal API used to create class macros such as
|
13
|
+
# +serialize+, and features like time zone aware attributes.
|
14
|
+
#
|
15
|
+
# Used to wrap the type of an attribute in a new type.
|
16
|
+
# When the schema for a model is loaded, attributes with the same name as
|
17
|
+
# +column_name+ will have their type yielded to the given block. The
|
18
|
+
# return value of that block will be used instead.
|
19
|
+
#
|
20
|
+
# Subsequent calls where +column_name+ and +decorator_name+ are the same
|
21
|
+
# will override the previous decorator, not decorate twice. This can be
|
22
|
+
# used to create idempotent class macros like +serialize+
|
11
23
|
def decorate_attribute_type(column_name, decorator_name, &block)
|
12
24
|
matcher = ->(name, _) { name == column_name.to_s }
|
13
25
|
key = "_#{column_name}_#{decorator_name}"
|
14
26
|
decorate_matching_attribute_types(matcher, key, &block)
|
15
27
|
end
|
16
28
|
|
29
|
+
# This method is an internal API used to create higher level features like
|
30
|
+
# time zone aware attributes.
|
31
|
+
#
|
32
|
+
# When the schema for a model is loaded, +matcher+ will be called for each
|
33
|
+
# attribute with its name and type. If the matcher returns a truthy value,
|
34
|
+
# the type will then be yielded to the given block, and the return value
|
35
|
+
# of that block will replace the type.
|
36
|
+
#
|
37
|
+
# Subsequent calls to this method with the same value for +decorator_name+
|
38
|
+
# will replace the previous decorator, not decorate twice. This can be
|
39
|
+
# used to ensure that class macros are idempotent.
|
17
40
|
def decorate_matching_attribute_types(matcher, decorator_name, &block)
|
18
41
|
reload_schema_from_cache
|
19
42
|
decorator_name = decorator_name.to_s
|
@@ -24,13 +47,13 @@ module ActiveRecord
|
|
24
47
|
|
25
48
|
private
|
26
49
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
50
|
+
def load_schema!
|
51
|
+
super
|
52
|
+
attribute_types.each do |name, type|
|
53
|
+
decorated_type = attribute_type_decorations.apply(name, type)
|
54
|
+
define_attribute(name, decorated_type)
|
55
|
+
end
|
32
56
|
end
|
33
|
-
end
|
34
57
|
end
|
35
58
|
|
36
59
|
class TypeDecorator # :nodoc:
|
@@ -53,15 +76,15 @@ module ActiveRecord
|
|
53
76
|
|
54
77
|
private
|
55
78
|
|
56
|
-
|
57
|
-
|
58
|
-
|
79
|
+
def decorators_for(name, type)
|
80
|
+
matching(name, type).map(&:last)
|
81
|
+
end
|
59
82
|
|
60
|
-
|
61
|
-
|
62
|
-
|
83
|
+
def matching(name, type)
|
84
|
+
@decorations.values.select do |(matcher, _)|
|
85
|
+
matcher.call(name, type)
|
86
|
+
end
|
63
87
|
end
|
64
|
-
end
|
65
88
|
end
|
66
89
|
end
|
67
90
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
# = Active Record Attribute Methods Before Type Cast
|
@@ -44,6 +46,7 @@ module ActiveRecord
|
|
44
46
|
# task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
|
45
47
|
# task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21"
|
46
48
|
def read_attribute_before_type_cast(attr_name)
|
49
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
47
50
|
@attributes[attr_name.to_s].value_before_type_cast
|
48
51
|
end
|
49
52
|
|
@@ -58,19 +61,21 @@ module ActiveRecord
|
|
58
61
|
# task.attributes_before_type_cast
|
59
62
|
# # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
|
60
63
|
def attributes_before_type_cast
|
64
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
61
65
|
@attributes.values_before_type_cast
|
62
66
|
end
|
63
67
|
|
64
68
|
private
|
65
69
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
+
# Dispatch target for <tt>*_before_type_cast</tt> attribute methods.
|
71
|
+
def attribute_before_type_cast(attribute_name)
|
72
|
+
read_attribute_before_type_cast(attribute_name)
|
73
|
+
end
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
|
75
|
+
def attribute_came_from_user?(attribute_name)
|
76
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
77
|
+
@attributes[attribute_name].came_from_user?
|
78
|
+
end
|
74
79
|
end
|
75
80
|
end
|
76
81
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/attribute_accessors"
|
3
4
|
|
4
5
|
module ActiveRecord
|
5
6
|
module AttributeMethods
|
6
|
-
module Dirty
|
7
|
+
module Dirty
|
7
8
|
extend ActiveSupport::Concern
|
8
9
|
|
9
10
|
include ActiveModel::Dirty
|
@@ -13,139 +14,208 @@ module ActiveRecord
|
|
13
14
|
raise "You cannot include Dirty after Timestamp"
|
14
15
|
end
|
15
16
|
|
16
|
-
class_attribute :partial_writes, instance_writer: false
|
17
|
-
self.partial_writes = true
|
18
|
-
end
|
17
|
+
class_attribute :partial_writes, instance_writer: false, default: true
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
status
|
26
|
-
end
|
19
|
+
# Attribute methods for "changed in last call to save?"
|
20
|
+
attribute_method_affix(prefix: "saved_change_to_", suffix: "?")
|
21
|
+
attribute_method_prefix("saved_change_to_")
|
22
|
+
attribute_method_suffix("_before_last_save")
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
changes_applied
|
32
|
-
end
|
24
|
+
# Attribute methods for "will change if I call save?"
|
25
|
+
attribute_method_affix(prefix: "will_save_change_to_", suffix: "?")
|
26
|
+
attribute_method_suffix("_change_to_be_saved", "_in_database")
|
33
27
|
end
|
34
28
|
|
35
29
|
# <tt>reload</tt> the record and clears changed attributes.
|
36
30
|
def reload(*)
|
37
31
|
super.tap do
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@changed_attributes = HashWithIndifferentAccess.new
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def initialize_dup(other) # :nodoc:
|
45
|
-
super
|
46
|
-
@attributes = self.class._default_attributes.map do |attr|
|
47
|
-
attr.with_value_from_user(@attributes.fetch_value(attr.name))
|
32
|
+
@mutations_before_last_save = nil
|
33
|
+
@mutations_from_database = nil
|
48
34
|
end
|
49
|
-
@mutation_tracker = nil
|
50
|
-
end
|
51
|
-
|
52
|
-
def changes_applied
|
53
|
-
@previous_mutation_tracker = mutation_tracker
|
54
|
-
@changed_attributes = HashWithIndifferentAccess.new
|
55
|
-
store_original_attributes
|
56
|
-
end
|
57
|
-
|
58
|
-
def clear_changes_information
|
59
|
-
@previous_mutation_tracker = nil
|
60
|
-
@changed_attributes = HashWithIndifferentAccess.new
|
61
|
-
store_original_attributes
|
62
35
|
end
|
63
36
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
37
|
+
# Did this attribute change when we last saved?
|
38
|
+
#
|
39
|
+
# This method is useful in after callbacks to determine if an attribute
|
40
|
+
# was changed during the save that triggered the callbacks to run. It can
|
41
|
+
# be invoked as +saved_change_to_name?+ instead of
|
42
|
+
# <tt>saved_change_to_attribute?("name")</tt>.
|
43
|
+
#
|
44
|
+
# ==== Options
|
45
|
+
#
|
46
|
+
# +from+ When passed, this method will return false unless the original
|
47
|
+
# value is equal to the given option
|
48
|
+
#
|
49
|
+
# +to+ When passed, this method will return false unless the value was
|
50
|
+
# changed to the given value
|
51
|
+
def saved_change_to_attribute?(attr_name, **options)
|
52
|
+
mutations_before_last_save.changed?(attr_name.to_s, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the change to an attribute during the last save. If the
|
56
|
+
# attribute was changed, the result will be an array containing the
|
57
|
+
# original value and the saved value.
|
58
|
+
#
|
59
|
+
# This method is useful in after callbacks, to see the change in an
|
60
|
+
# attribute during the save that triggered the callbacks to run. It can be
|
61
|
+
# invoked as +saved_change_to_name+ instead of
|
62
|
+
# <tt>saved_change_to_attribute("name")</tt>.
|
63
|
+
def saved_change_to_attribute(attr_name)
|
64
|
+
mutations_before_last_save.change_to_attribute(attr_name.to_s)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the original value of an attribute before the last save.
|
68
|
+
#
|
69
|
+
# This method is useful in after callbacks to get the original value of an
|
70
|
+
# attribute before the save that triggered the callbacks to run. It can be
|
71
|
+
# invoked as +name_before_last_save+ instead of
|
72
|
+
# <tt>attribute_before_last_save("name")</tt>.
|
73
|
+
def attribute_before_last_save(attr_name)
|
74
|
+
mutations_before_last_save.original_value(attr_name.to_s)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Did the last call to +save+ have any changes to change?
|
78
|
+
def saved_changes?
|
79
|
+
mutations_before_last_save.any_changes?
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns a hash containing all the changes that were just saved.
|
83
|
+
def saved_changes
|
84
|
+
mutations_before_last_save.changes
|
85
|
+
end
|
86
|
+
|
87
|
+
# Will this attribute change the next time we save?
|
88
|
+
#
|
89
|
+
# This method is useful in validations and before callbacks to determine
|
90
|
+
# if the next call to +save+ will change a particular attribute. It can be
|
91
|
+
# invoked as +will_save_change_to_name?+ instead of
|
92
|
+
# <tt>will_save_change_to_attribute("name")</tt>.
|
93
|
+
#
|
94
|
+
# ==== Options
|
95
|
+
#
|
96
|
+
# +from+ When passed, this method will return false unless the original
|
97
|
+
# value is equal to the given option
|
98
|
+
#
|
99
|
+
# +to+ When passed, this method will return false unless the value will be
|
100
|
+
# changed to the given value
|
101
|
+
def will_save_change_to_attribute?(attr_name, **options)
|
102
|
+
mutations_from_database.changed?(attr_name.to_s, options)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns the change to an attribute that will be persisted during the
|
106
|
+
# next save.
|
107
|
+
#
|
108
|
+
# This method is useful in validations and before callbacks, to see the
|
109
|
+
# change to an attribute that will occur when the record is saved. It can
|
110
|
+
# be invoked as +name_change_to_be_saved+ instead of
|
111
|
+
# <tt>attribute_change_to_be_saved("name")</tt>.
|
112
|
+
#
|
113
|
+
# If the attribute will change, the result will be an array containing the
|
114
|
+
# original value and the new value about to be saved.
|
115
|
+
def attribute_change_to_be_saved(attr_name)
|
116
|
+
mutations_from_database.change_to_attribute(attr_name.to_s)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns the value of an attribute in the database, as opposed to the
|
120
|
+
# in-memory value that will be persisted the next time the record is
|
121
|
+
# saved.
|
122
|
+
#
|
123
|
+
# This method is useful in validations and before callbacks, to see the
|
124
|
+
# original value of an attribute prior to any changes about to be
|
125
|
+
# saved. It can be invoked as +name_in_database+ instead of
|
126
|
+
# <tt>attribute_in_database("name")</tt>.
|
127
|
+
def attribute_in_database(attr_name)
|
128
|
+
mutations_from_database.original_value(attr_name.to_s)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Will the next call to +save+ have any changes to persist?
|
132
|
+
def has_changes_to_save?
|
133
|
+
mutations_from_database.any_changes?
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns a hash containing all the changes that will be persisted during
|
137
|
+
# the next save.
|
138
|
+
def changes_to_save
|
139
|
+
mutations_from_database.changes
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns an array of the names of any attributes that will change when
|
143
|
+
# the record is next saved.
|
144
|
+
def changed_attribute_names_to_save
|
145
|
+
mutations_from_database.changed_attribute_names
|
146
|
+
end
|
147
|
+
|
148
|
+
# Returns a hash of the attributes that will change when the record is
|
149
|
+
# next saved.
|
150
|
+
#
|
151
|
+
# The hash keys are the attribute names, and the hash values are the
|
152
|
+
# original attribute values in the database (as opposed to the in-memory
|
153
|
+
# values about to be saved).
|
154
|
+
def attributes_in_database
|
155
|
+
mutations_from_database.changed_values
|
75
156
|
end
|
76
157
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
@cached_changed_attributes
|
82
|
-
else
|
83
|
-
super.reverse_merge(mutation_tracker.changed_values).freeze
|
158
|
+
private
|
159
|
+
def mutations_from_database
|
160
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
161
|
+
super
|
84
162
|
end
|
85
|
-
end
|
86
163
|
|
87
|
-
|
88
|
-
|
164
|
+
def mutations_before_last_save
|
165
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
89
166
|
super
|
90
167
|
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def previous_changes
|
94
|
-
previous_mutation_tracker.changes
|
95
|
-
end
|
96
|
-
|
97
|
-
def attribute_changed_in_place?(attr_name)
|
98
|
-
mutation_tracker.changed_in_place?(attr_name)
|
99
|
-
end
|
100
168
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
@mutation_tracker = nil
|
169
|
+
def write_attribute_without_type_cast(attr_name, value)
|
170
|
+
result = super
|
171
|
+
clear_attribute_change(attr_name)
|
172
|
+
result
|
106
173
|
end
|
107
|
-
@mutation_tracker ||= AttributeMutationTracker.new(@attributes)
|
108
|
-
end
|
109
174
|
|
110
|
-
|
111
|
-
|
112
|
-
end
|
175
|
+
def _touch_row(attribute_names, time)
|
176
|
+
@_touch_attr_names = Set.new(attribute_names)
|
113
177
|
|
114
|
-
|
115
|
-
mutation_tracker.forget_change(attr_name)
|
116
|
-
end
|
178
|
+
affected_rows = super
|
117
179
|
|
118
|
-
|
119
|
-
|
120
|
-
|
180
|
+
if @_skip_dirty_tracking ||= false
|
181
|
+
clear_attribute_changes(@_touch_attr_names)
|
182
|
+
return affected_rows
|
183
|
+
end
|
121
184
|
|
122
|
-
|
123
|
-
|
124
|
-
|
185
|
+
changes = {}
|
186
|
+
@attributes.keys.each do |attr_name|
|
187
|
+
next if @_touch_attr_names.include?(attr_name)
|
125
188
|
|
126
|
-
|
127
|
-
|
128
|
-
|
189
|
+
if attribute_changed?(attr_name)
|
190
|
+
changes[attr_name] = _read_attribute(attr_name)
|
191
|
+
_write_attribute(attr_name, attribute_was(attr_name))
|
192
|
+
clear_attribute_change(attr_name)
|
193
|
+
end
|
194
|
+
end
|
129
195
|
|
130
|
-
|
131
|
-
|
132
|
-
@mutation_tracker = nil
|
133
|
-
end
|
196
|
+
changes_applied
|
197
|
+
changes.each { |attr_name, value| _write_attribute(attr_name, value) }
|
134
198
|
|
135
|
-
|
136
|
-
|
137
|
-
|
199
|
+
affected_rows
|
200
|
+
ensure
|
201
|
+
@_touch_attr_names, @_skip_dirty_tracking = nil, nil
|
202
|
+
end
|
138
203
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
204
|
+
def _update_record(attribute_names = attribute_names_for_partial_writes)
|
205
|
+
affected_rows = super
|
206
|
+
changes_applied
|
207
|
+
affected_rows
|
208
|
+
end
|
145
209
|
|
146
|
-
|
147
|
-
|
148
|
-
|
210
|
+
def _create_record(attribute_names = attribute_names_for_partial_writes)
|
211
|
+
id = super
|
212
|
+
changes_applied
|
213
|
+
id
|
214
|
+
end
|
215
|
+
|
216
|
+
def attribute_names_for_partial_writes
|
217
|
+
partial_writes? ? changed_attribute_names_to_save : attribute_names
|
218
|
+
end
|
149
219
|
end
|
150
220
|
end
|
151
221
|
end
|