activerecord 4.2.8 → 6.0.0
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 +612 -1583
- data/MIT-LICENSE +4 -2
- data/README.rdoc +13 -12
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record.rb +41 -22
- data/lib/active_record/aggregations.rb +267 -251
- data/lib/active_record/association_relation.rb +11 -6
- data/lib/active_record/associations.rb +1737 -1597
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +125 -58
- data/lib/active_record/associations/association_scope.rb +103 -132
- data/lib/active_record/associations/belongs_to_association.rb +65 -60
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +27 -40
- data/lib/active_record/associations/builder/belongs_to.rb +69 -55
- data/lib/active_record/associations/builder/collection_association.rb +10 -33
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
- data/lib/active_record/associations/builder/has_many.rb +8 -4
- data/lib/active_record/associations/builder/has_one.rb +46 -5
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +134 -286
- data/lib/active_record/associations/collection_proxy.rb +241 -146
- data/lib/active_record/associations/foreign_association.rb +10 -1
- data/lib/active_record/associations/has_many_association.rb +34 -97
- data/lib/active_record/associations/has_many_through_association.rb +60 -87
- data/lib/active_record/associations/has_one_association.rb +61 -49
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +137 -167
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -88
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/preloader.rb +90 -92
- data/lib/active_record/associations/preloader/association.rb +90 -123
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/singular_association.rb +18 -39
- data/lib/active_record/associations/through_association.rb +38 -18
- data/lib/active_record/attribute_assignment.rb +56 -183
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods.rb +120 -135
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
- data/lib/active_record/attribute_methods/dirty.rb +174 -144
- data/lib/active_record/attribute_methods/primary_key.rb +91 -83
- data/lib/active_record/attribute_methods/query.rb +6 -5
- data/lib/active_record/attribute_methods/read.rb +20 -76
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
- data/lib/active_record/attribute_methods/write.rb +32 -54
- data/lib/active_record/attributes.rb +214 -82
- data/lib/active_record/autosave_association.rb +91 -37
- data/lib/active_record/base.rb +57 -45
- data/lib/active_record/callbacks.rb +100 -74
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -296
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -244
- data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
- data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -627
- data/lib/active_record/connection_adapters/column.rb +56 -43
- data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -188
- data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
- 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 +31 -19
- 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 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +470 -290
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +551 -356
- data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- 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 +290 -345
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +176 -41
- data/lib/active_record/core.rb +251 -231
- data/lib/active_record/counter_cache.rb +67 -49
- 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 +79 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +163 -86
- data/lib/active_record/errors.rb +188 -53
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +35 -9
- 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 +228 -499
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +158 -112
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +123 -29
- data/lib/active_record/internal_metadata.rb +53 -0
- data/lib/active_record/legacy_yaml_adapter.rb +21 -3
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +87 -96
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +76 -33
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +626 -283
- data/lib/active_record/migration/command_recorder.rb +177 -90
- data/lib/active_record/migration/compatibility.rb +244 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/model_schema.rb +314 -112
- data/lib/active_record/nested_attributes.rb +264 -222
- data/lib/active_record/no_touching.rb +14 -1
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +557 -125
- data/lib/active_record/query_cache.rb +19 -23
- data/lib/active_record/querying.rb +43 -29
- data/lib/active_record/railtie.rb +147 -46
- 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 +330 -197
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +428 -279
- data/lib/active_record/relation.rb +518 -341
- data/lib/active_record/relation/batches.rb +207 -55
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/calculations.rb +267 -253
- data/lib/active_record/relation/delegation.rb +70 -80
- data/lib/active_record/relation/finder_methods.rb +277 -241
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +78 -87
- data/lib/active_record/relation/predicate_builder.rb +114 -119
- data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +575 -394
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +11 -13
- data/lib/active_record/relation/where_clause.rb +190 -0
- data/lib/active_record/relation/where_clause_factory.rb +33 -0
- data/lib/active_record/result.rb +79 -42
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +144 -121
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +112 -93
- data/lib/active_record/schema_migration.rb +24 -17
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/scoping/default.rb +101 -85
- data/lib/active_record/scoping/named.rb +86 -33
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +73 -36
- data/lib/active_record/store.rb +127 -42
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +75 -0
- data/lib/active_record/tasks/database_tasks.rb +308 -99
- data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
- data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -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 +86 -40
- data/lib/active_record/touch_later.rb +66 -0
- data/lib/active_record/transactions.rb +216 -150
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +78 -23
- data/lib/active_record/type/adapter_specific_registry.rb +129 -0
- data/lib/active_record/type/date.rb +4 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +24 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/type_caster/connection.rb +34 -0
- data/lib/active_record/type_caster/map.rb +20 -0
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +42 -55
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +51 -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 +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.rb +20 -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/window_predications.rb +9 -0
- data/lib/rails/generators/active_record.rb +7 -5
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration.rb +31 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +164 -60
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- 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 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -163
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -58
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,35 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# See ActiveRecord::Transactions::ClassMethods for documentation.
|
3
5
|
module Transactions
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
#:nodoc:
|
6
8
|
ACTIONS = [:create, :destroy, :update]
|
7
|
-
#:nodoc:
|
8
|
-
CALLBACK_WARN_MESSAGE = "Currently, Active Record suppresses errors raised " \
|
9
|
-
"within `after_rollback`/`after_commit` callbacks and only print them to " \
|
10
|
-
"the logs. In the next version, these errors will no longer be suppressed. " \
|
11
|
-
"Instead, the errors will propagate normally just like in other Active " \
|
12
|
-
"Record callbacks.\n" \
|
13
|
-
"\n" \
|
14
|
-
"You can opt into the new behavior and remove this warning by setting:\n" \
|
15
|
-
"\n" \
|
16
|
-
" config.active_record.raise_in_transactional_callbacks = true\n\n"
|
17
9
|
|
18
10
|
included do
|
19
11
|
define_callbacks :commit, :rollback,
|
20
|
-
|
12
|
+
:before_commit,
|
13
|
+
:before_commit_without_transaction_enrollment,
|
14
|
+
:commit_without_transaction_enrollment,
|
15
|
+
:rollback_without_transaction_enrollment,
|
21
16
|
scope: [:kind, :name]
|
22
|
-
|
23
|
-
mattr_accessor :raise_in_transactional_callbacks, instance_writer: false
|
24
|
-
self.raise_in_transactional_callbacks = false
|
25
17
|
end
|
26
18
|
|
27
19
|
# = Active Record Transactions
|
28
20
|
#
|
29
|
-
# Transactions are protective blocks where SQL statements are only permanent
|
21
|
+
# \Transactions are protective blocks where SQL statements are only permanent
|
30
22
|
# if they can all succeed as one atomic action. The classic example is a
|
31
23
|
# transfer between two accounts where you can only have a deposit if the
|
32
|
-
# withdrawal succeeded and vice versa. Transactions enforce the integrity of
|
24
|
+
# withdrawal succeeded and vice versa. \Transactions enforce the integrity of
|
33
25
|
# the database and guard the data against program errors or database
|
34
26
|
# break-downs. So basically you should use transaction blocks whenever you
|
35
27
|
# have a number of statements that must be executed together or not at all.
|
@@ -49,20 +41,20 @@ module ActiveRecord
|
|
49
41
|
#
|
50
42
|
# == Different Active Record classes in a single transaction
|
51
43
|
#
|
52
|
-
# Though the transaction class method is called on some Active Record class,
|
44
|
+
# Though the #transaction class method is called on some Active Record class,
|
53
45
|
# the objects within the transaction block need not all be instances of
|
54
46
|
# that class. This is because transactions are per-database connection, not
|
55
47
|
# per-model.
|
56
48
|
#
|
57
49
|
# In this example a +balance+ record is transactionally saved even
|
58
|
-
# though
|
50
|
+
# though #transaction is called on the +Account+ class:
|
59
51
|
#
|
60
52
|
# Account.transaction do
|
61
53
|
# balance.save!
|
62
54
|
# account.save!
|
63
55
|
# end
|
64
56
|
#
|
65
|
-
# The
|
57
|
+
# The #transaction method is also available as a model instance method.
|
66
58
|
# For example, you can also do this:
|
67
59
|
#
|
68
60
|
# balance.transaction do
|
@@ -89,7 +81,8 @@ module ActiveRecord
|
|
89
81
|
#
|
90
82
|
# == +save+ and +destroy+ are automatically wrapped in a transaction
|
91
83
|
#
|
92
|
-
# Both
|
84
|
+
# Both {#save}[rdoc-ref:Persistence#save] and
|
85
|
+
# {#destroy}[rdoc-ref:Persistence#destroy] come wrapped in a transaction that ensures
|
93
86
|
# that whatever you do in validations or callbacks will happen under its
|
94
87
|
# protected cover. So you can use validations to check for values that
|
95
88
|
# the transaction depends on or you can raise exceptions in the callbacks
|
@@ -98,7 +91,7 @@ module ActiveRecord
|
|
98
91
|
# As a consequence changes to the database are not seen outside your connection
|
99
92
|
# until the operation is complete. For example, if you try to update the index
|
100
93
|
# of a search engine in +after_save+ the indexer won't see the updated record.
|
101
|
-
# The
|
94
|
+
# The #after_commit callback is the only one that is triggered once the update
|
102
95
|
# is committed. See below.
|
103
96
|
#
|
104
97
|
# == Exception handling and rolling back
|
@@ -107,11 +100,11 @@ module ActiveRecord
|
|
107
100
|
# be propagated (after triggering the ROLLBACK), so you should be ready to
|
108
101
|
# catch those in your application code.
|
109
102
|
#
|
110
|
-
# One exception is the
|
103
|
+
# One exception is the ActiveRecord::Rollback exception, which will trigger
|
111
104
|
# a ROLLBACK when raised, but not be re-raised by the transaction block.
|
112
105
|
#
|
113
|
-
# *Warning*: one should not catch
|
114
|
-
# inside a transaction block.
|
106
|
+
# *Warning*: one should not catch ActiveRecord::StatementInvalid exceptions
|
107
|
+
# inside a transaction block. ActiveRecord::StatementInvalid exceptions indicate that an
|
115
108
|
# error occurred at the database level, for example when a unique constraint
|
116
109
|
# is violated. On some database systems, such as PostgreSQL, database errors
|
117
110
|
# inside a transaction cause the entire transaction to become unusable
|
@@ -132,16 +125,16 @@ module ActiveRecord
|
|
132
125
|
# # statement will cause a PostgreSQL error, even though the unique
|
133
126
|
# # constraint is no longer violated:
|
134
127
|
# Number.create(i: 1)
|
135
|
-
# # => "
|
128
|
+
# # => "PG::Error: ERROR: current transaction is aborted, commands
|
136
129
|
# # ignored until end of transaction block"
|
137
130
|
# end
|
138
131
|
#
|
139
132
|
# One should restart the entire transaction if an
|
140
|
-
#
|
133
|
+
# ActiveRecord::StatementInvalid occurred.
|
141
134
|
#
|
142
135
|
# == Nested transactions
|
143
136
|
#
|
144
|
-
#
|
137
|
+
# #transaction calls can be nested. By default, this makes all database
|
145
138
|
# statements in the nested transaction block become part of the parent
|
146
139
|
# transaction. For example, the following behavior may be surprising:
|
147
140
|
#
|
@@ -153,7 +146,7 @@ module ActiveRecord
|
|
153
146
|
# end
|
154
147
|
# end
|
155
148
|
#
|
156
|
-
# creates both "Kotori" and "Nemu". Reason is the
|
149
|
+
# creates both "Kotori" and "Nemu". Reason is the ActiveRecord::Rollback
|
157
150
|
# exception in the nested block does not issue a ROLLBACK. Since these exceptions
|
158
151
|
# are captured in transaction blocks, the parent block does not see it and the
|
159
152
|
# real transaction is committed.
|
@@ -177,28 +170,28 @@ module ActiveRecord
|
|
177
170
|
# writing, the only database that we're aware of that supports true nested
|
178
171
|
# transactions, is MS-SQL. Because of this, Active Record emulates nested
|
179
172
|
# transactions by using savepoints on MySQL and PostgreSQL. See
|
180
|
-
#
|
173
|
+
# https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
|
181
174
|
# for more information about savepoints.
|
182
175
|
#
|
183
|
-
# === Callbacks
|
176
|
+
# === \Callbacks
|
184
177
|
#
|
185
178
|
# There are two types of callbacks associated with committing and rolling back transactions:
|
186
|
-
#
|
179
|
+
# #after_commit and #after_rollback.
|
187
180
|
#
|
188
|
-
#
|
189
|
-
# transaction immediately after the transaction is committed.
|
181
|
+
# #after_commit callbacks are called on every record saved or destroyed within a
|
182
|
+
# transaction immediately after the transaction is committed. #after_rollback callbacks
|
190
183
|
# are called on every record saved or destroyed within a transaction immediately after the
|
191
184
|
# transaction or savepoint is rolled back.
|
192
185
|
#
|
193
186
|
# These callbacks are useful for interacting with other systems since you will be guaranteed
|
194
187
|
# that the callback is only executed when the database is in a permanent state. For example,
|
195
|
-
#
|
188
|
+
# #after_commit is a good spot to put in a hook to clearing a cache since clearing it from
|
196
189
|
# within a transaction could trigger the cache to be regenerated before the database is updated.
|
197
190
|
#
|
198
191
|
# === Caveats
|
199
192
|
#
|
200
|
-
# If you're on MySQL, then do not use DDL operations in nested
|
201
|
-
# blocks that are emulated with savepoints. That is, do not execute statements
|
193
|
+
# If you're on MySQL, then do not use Data Definition Language (DDL) operations in nested
|
194
|
+
# transactions blocks that are emulated with savepoints. That is, do not execute statements
|
202
195
|
# like 'CREATE TABLE' inside such blocks. This is because MySQL automatically
|
203
196
|
# releases all savepoints upon executing a DDL operation. When +transaction+
|
204
197
|
# is finished and tries to release the savepoint it created earlier, a
|
@@ -206,20 +199,24 @@ module ActiveRecord
|
|
206
199
|
# automatically released. The following example demonstrates the problem:
|
207
200
|
#
|
208
201
|
# Model.connection.transaction do # BEGIN
|
209
|
-
# Model.connection.transaction(requires_new: true) do
|
202
|
+
# Model.connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1
|
210
203
|
# Model.connection.create_table(...) # active_record_1 now automatically released
|
211
|
-
# end # RELEASE
|
204
|
+
# end # RELEASE SAVEPOINT active_record_1
|
212
205
|
# # ^^^^ BOOM! database error!
|
213
206
|
# end
|
214
207
|
#
|
215
208
|
# Note that "TRUNCATE" is also a MySQL DDL statement!
|
216
209
|
module ClassMethods
|
217
|
-
# See
|
210
|
+
# See the ConnectionAdapters::DatabaseStatements#transaction API docs.
|
218
211
|
def transaction(options = {}, &block)
|
219
|
-
# See the ConnectionAdapters::DatabaseStatements#transaction API docs.
|
220
212
|
connection.transaction(options, &block)
|
221
213
|
end
|
222
214
|
|
215
|
+
def before_commit(*args, &block) # :nodoc:
|
216
|
+
set_options_for_callbacks!(args)
|
217
|
+
set_callback(:before_commit, :before, *args, &block)
|
218
|
+
end
|
219
|
+
|
223
220
|
# This callback is called after a record has been created, updated, or destroyed.
|
224
221
|
#
|
225
222
|
# You can specify that the callback should only be fired by a certain action with
|
@@ -232,44 +229,77 @@ module ActiveRecord
|
|
232
229
|
# after_commit :do_foo_bar, on: [:create, :update]
|
233
230
|
# after_commit :do_bar_baz, on: [:update, :destroy]
|
234
231
|
#
|
235
|
-
# Note that transactional fixtures do not play well with this feature. Please
|
236
|
-
# use the +test_after_commit+ gem to have these hooks fired in tests.
|
237
232
|
def after_commit(*args, &block)
|
238
233
|
set_options_for_callbacks!(args)
|
239
234
|
set_callback(:commit, :after, *args, &block)
|
240
|
-
|
241
|
-
|
242
|
-
|
235
|
+
end
|
236
|
+
|
237
|
+
# Shortcut for <tt>after_commit :hook, on: [ :create, :update ]</tt>.
|
238
|
+
def after_save_commit(*args, &block)
|
239
|
+
set_options_for_callbacks!(args, on: [ :create, :update ])
|
240
|
+
set_callback(:commit, :after, *args, &block)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Shortcut for <tt>after_commit :hook, on: :create</tt>.
|
244
|
+
def after_create_commit(*args, &block)
|
245
|
+
set_options_for_callbacks!(args, on: :create)
|
246
|
+
set_callback(:commit, :after, *args, &block)
|
247
|
+
end
|
248
|
+
|
249
|
+
# Shortcut for <tt>after_commit :hook, on: :update</tt>.
|
250
|
+
def after_update_commit(*args, &block)
|
251
|
+
set_options_for_callbacks!(args, on: :update)
|
252
|
+
set_callback(:commit, :after, *args, &block)
|
253
|
+
end
|
254
|
+
|
255
|
+
# Shortcut for <tt>after_commit :hook, on: :destroy</tt>.
|
256
|
+
def after_destroy_commit(*args, &block)
|
257
|
+
set_options_for_callbacks!(args, on: :destroy)
|
258
|
+
set_callback(:commit, :after, *args, &block)
|
243
259
|
end
|
244
260
|
|
245
261
|
# This callback is called after a create, update, or destroy are rolled back.
|
246
262
|
#
|
247
|
-
# Please check the documentation of
|
263
|
+
# Please check the documentation of #after_commit for options.
|
248
264
|
def after_rollback(*args, &block)
|
249
265
|
set_options_for_callbacks!(args)
|
250
266
|
set_callback(:rollback, :after, *args, &block)
|
251
|
-
|
252
|
-
|
253
|
-
|
267
|
+
end
|
268
|
+
|
269
|
+
def before_commit_without_transaction_enrollment(*args, &block) # :nodoc:
|
270
|
+
set_options_for_callbacks!(args)
|
271
|
+
set_callback(:before_commit_without_transaction_enrollment, :before, *args, &block)
|
272
|
+
end
|
273
|
+
|
274
|
+
def after_commit_without_transaction_enrollment(*args, &block) # :nodoc:
|
275
|
+
set_options_for_callbacks!(args)
|
276
|
+
set_callback(:commit_without_transaction_enrollment, :after, *args, &block)
|
277
|
+
end
|
278
|
+
|
279
|
+
def after_rollback_without_transaction_enrollment(*args, &block) # :nodoc:
|
280
|
+
set_options_for_callbacks!(args)
|
281
|
+
set_callback(:rollback_without_transaction_enrollment, :after, *args, &block)
|
254
282
|
end
|
255
283
|
|
256
284
|
private
|
257
285
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
286
|
+
def set_options_for_callbacks!(args, enforced_options = {})
|
287
|
+
options = args.extract_options!.merge!(enforced_options)
|
288
|
+
args << options
|
289
|
+
|
290
|
+
if options[:on]
|
291
|
+
fire_on = Array(options[:on])
|
292
|
+
assert_valid_transaction_action(fire_on)
|
293
|
+
options[:if] = Array(options[:if])
|
294
|
+
options[:if].unshift(-> { transaction_include_any_action?(fire_on) })
|
295
|
+
end
|
265
296
|
end
|
266
|
-
end
|
267
297
|
|
268
|
-
|
269
|
-
|
270
|
-
|
298
|
+
def assert_valid_transaction_action(actions)
|
299
|
+
if (actions - ACTIONS).any?
|
300
|
+
raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS}"
|
301
|
+
end
|
271
302
|
end
|
272
|
-
end
|
273
303
|
end
|
274
304
|
|
275
305
|
# See ActiveRecord::Transactions::ClassMethods for detailed documentation.
|
@@ -282,9 +312,7 @@ module ActiveRecord
|
|
282
312
|
end
|
283
313
|
|
284
314
|
def save(*) #:nodoc:
|
285
|
-
|
286
|
-
with_transaction_returning_status { super }
|
287
|
-
end
|
315
|
+
with_transaction_returning_status { super }
|
288
316
|
end
|
289
317
|
|
290
318
|
def save!(*) #:nodoc:
|
@@ -295,48 +323,38 @@ module ActiveRecord
|
|
295
323
|
with_transaction_returning_status { super }
|
296
324
|
end
|
297
325
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
yield
|
302
|
-
rescue Exception
|
303
|
-
restore_transaction_record_state
|
304
|
-
raise
|
305
|
-
ensure
|
306
|
-
clear_transaction_record_state
|
326
|
+
def before_committed! # :nodoc:
|
327
|
+
_run_before_commit_without_transaction_enrollment_callbacks
|
328
|
+
_run_before_commit_callbacks
|
307
329
|
end
|
308
330
|
|
309
|
-
# Call the
|
331
|
+
# Call the #after_commit callbacks.
|
310
332
|
#
|
311
333
|
# Ensure that it is not called if the object was never persisted (failed create),
|
312
334
|
# but call it after the commit of a destroyed object.
|
313
|
-
def committed!(should_run_callbacks
|
314
|
-
|
335
|
+
def committed!(should_run_callbacks: true) #:nodoc:
|
336
|
+
if should_run_callbacks
|
337
|
+
@_committed_already_called = true
|
338
|
+
_run_commit_without_transaction_enrollment_callbacks
|
339
|
+
_run_commit_callbacks
|
340
|
+
end
|
315
341
|
ensure
|
342
|
+
@_committed_already_called = false
|
316
343
|
force_clear_transaction_record_state
|
317
344
|
end
|
318
345
|
|
319
|
-
# Call the
|
346
|
+
# Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
|
320
347
|
# state should be rolled back to the beginning or just to the last savepoint.
|
321
|
-
def rolledback!(force_restore_state
|
322
|
-
|
348
|
+
def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
|
349
|
+
if should_run_callbacks
|
350
|
+
_run_rollback_callbacks
|
351
|
+
_run_rollback_without_transaction_enrollment_callbacks
|
352
|
+
end
|
323
353
|
ensure
|
324
354
|
restore_transaction_record_state(force_restore_state)
|
325
355
|
clear_transaction_record_state
|
326
356
|
end
|
327
357
|
|
328
|
-
# Add the record to the current transaction so that the +after_rollback+ and +after_commit+ callbacks
|
329
|
-
# can be called.
|
330
|
-
def add_to_transaction
|
331
|
-
if has_transactional_callbacks?
|
332
|
-
self.class.connection.add_transaction_record(self)
|
333
|
-
else
|
334
|
-
sync_with_transaction_state
|
335
|
-
set_transaction_state(self.class.connection.transaction_state)
|
336
|
-
end
|
337
|
-
remember_transaction_record_state
|
338
|
-
end
|
339
|
-
|
340
358
|
# Executes +method+ within a transaction and captures its return value as a
|
341
359
|
# status flag. If the status is true the transaction is committed, otherwise
|
342
360
|
# a ROLLBACK is issued. In any case the status flag is returned.
|
@@ -346,82 +364,130 @@ module ActiveRecord
|
|
346
364
|
def with_transaction_returning_status
|
347
365
|
status = nil
|
348
366
|
self.class.transaction do
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
status = nil
|
367
|
+
if has_transactional_callbacks?
|
368
|
+
add_to_transaction
|
369
|
+
else
|
370
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
371
|
+
@transaction_state = self.class.connection.transaction_state
|
355
372
|
end
|
373
|
+
remember_transaction_record_state
|
356
374
|
|
375
|
+
status = yield
|
357
376
|
raise ActiveRecord::Rollback unless status
|
358
377
|
end
|
359
378
|
status
|
360
|
-
ensure
|
361
|
-
if @transaction_state && @transaction_state.committed?
|
362
|
-
clear_transaction_record_state
|
363
|
-
end
|
364
379
|
end
|
365
380
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
def remember_transaction_record_state #:nodoc:
|
370
|
-
@_start_transaction_state[:id] = id
|
371
|
-
@_start_transaction_state.reverse_merge!(
|
372
|
-
new_record: @new_record,
|
373
|
-
destroyed: @destroyed,
|
374
|
-
frozen?: frozen?,
|
375
|
-
)
|
376
|
-
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
|
381
|
+
def trigger_transactional_callbacks? # :nodoc:
|
382
|
+
(@_new_record_before_last_commit || _trigger_update_callback) && persisted? ||
|
383
|
+
_trigger_destroy_callback && destroyed?
|
377
384
|
end
|
378
385
|
|
379
|
-
|
380
|
-
|
381
|
-
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
|
382
|
-
force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
|
383
|
-
end
|
386
|
+
private
|
387
|
+
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
|
384
388
|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
+
# Save the new record state and id of a record so it can be restored later if a transaction fails.
|
390
|
+
def remember_transaction_record_state
|
391
|
+
@_start_transaction_state ||= {
|
392
|
+
id: id,
|
393
|
+
new_record: @new_record,
|
394
|
+
destroyed: @destroyed,
|
395
|
+
attributes: @attributes,
|
396
|
+
frozen?: frozen?,
|
397
|
+
level: 0
|
398
|
+
}
|
399
|
+
@_start_transaction_state[:level] += 1
|
400
|
+
|
401
|
+
if _committed_already_called
|
402
|
+
@_new_record_before_last_commit = false
|
403
|
+
else
|
404
|
+
@_new_record_before_last_commit = @_start_transaction_state[:new_record]
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
# Clear the new record state and id of a record.
|
409
|
+
def clear_transaction_record_state
|
410
|
+
return unless @_start_transaction_state
|
411
|
+
@_start_transaction_state[:level] -= 1
|
412
|
+
force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
|
413
|
+
end
|
414
|
+
|
415
|
+
# Force to clear the transaction record state.
|
416
|
+
def force_clear_transaction_record_state
|
417
|
+
@_start_transaction_state = nil
|
418
|
+
@transaction_state = nil
|
419
|
+
end
|
389
420
|
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
421
|
+
# Restore the new record state and id of a record that was previously saved by a call to save_record_state.
|
422
|
+
def restore_transaction_record_state(force_restore_state = false)
|
423
|
+
if restore_state = @_start_transaction_state
|
424
|
+
if force_restore_state || restore_state[:level] <= 1
|
425
|
+
@new_record = restore_state[:new_record]
|
426
|
+
@destroyed = restore_state[:destroyed]
|
427
|
+
@attributes = restore_state[:attributes].map do |attr|
|
428
|
+
value = @attributes.fetch_value(attr.name)
|
429
|
+
attr = attr.with_value_from_user(value) if attr.value != value
|
430
|
+
attr
|
431
|
+
end
|
432
|
+
@mutations_from_database = nil
|
433
|
+
@mutations_before_last_save = nil
|
434
|
+
if @attributes.fetch_value(@primary_key) != restore_state[:id]
|
435
|
+
@attributes.write_from_user(@primary_key, restore_state[:id])
|
436
|
+
end
|
437
|
+
freeze if restore_state[:frozen?]
|
402
438
|
end
|
403
|
-
freeze if restore_state[:frozen?]
|
404
439
|
end
|
405
440
|
end
|
406
|
-
end
|
407
441
|
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
442
|
+
# Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
|
443
|
+
def transaction_include_any_action?(actions)
|
444
|
+
actions.any? do |action|
|
445
|
+
case action
|
446
|
+
when :create
|
447
|
+
persisted? && @_new_record_before_last_commit
|
448
|
+
when :update
|
449
|
+
!(@_new_record_before_last_commit || destroyed?) && _trigger_update_callback
|
450
|
+
when :destroy
|
451
|
+
_trigger_destroy_callback
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
412
455
|
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
456
|
+
# Add the record to the current transaction so that the #after_rollback and #after_commit
|
457
|
+
# callbacks can be called.
|
458
|
+
def add_to_transaction
|
459
|
+
self.class.connection.add_transaction_record(self)
|
460
|
+
end
|
461
|
+
|
462
|
+
def has_transactional_callbacks?
|
463
|
+
!_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
|
464
|
+
end
|
465
|
+
|
466
|
+
# Updates the attributes on this particular Active Record object so that
|
467
|
+
# if it's associated with a transaction, then the state of the Active Record
|
468
|
+
# object will be updated to reflect the current state of the transaction.
|
469
|
+
#
|
470
|
+
# The <tt>@transaction_state</tt> variable stores the states of the associated
|
471
|
+
# transaction. This relies on the fact that a transaction can only be in
|
472
|
+
# one rollback or commit (otherwise a list of states would be required).
|
473
|
+
# Each Active Record object inside of a transaction carries that transaction's
|
474
|
+
# TransactionState.
|
475
|
+
#
|
476
|
+
# This method checks to see if the ActiveRecord object's state reflects
|
477
|
+
# the TransactionState, and rolls back or commits the Active Record object
|
478
|
+
# as appropriate.
|
479
|
+
def sync_with_transaction_state
|
480
|
+
if transaction_state = @transaction_state
|
481
|
+
if transaction_state.fully_committed?
|
482
|
+
force_clear_transaction_record_state
|
483
|
+
elsif transaction_state.committed?
|
484
|
+
clear_transaction_record_state
|
485
|
+
elsif transaction_state.rolledback?
|
486
|
+
force_restore_state = transaction_state.fully_rolledback?
|
487
|
+
restore_transaction_record_state(force_restore_state)
|
488
|
+
clear_transaction_record_state
|
489
|
+
end
|
423
490
|
end
|
424
491
|
end
|
425
|
-
end
|
426
492
|
end
|
427
493
|
end
|