activerecord 3.2.22.5 → 5.2.8
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 +657 -621
- data/MIT-LICENSE +2 -2
- data/README.rdoc +41 -46
- data/examples/performance.rb +55 -42
- data/examples/simple.rb +6 -5
- data/lib/active_record/aggregations.rb +264 -236
- data/lib/active_record/association_relation.rb +40 -0
- data/lib/active_record/associations/alias_tracker.rb +47 -42
- data/lib/active_record/associations/association.rb +127 -75
- data/lib/active_record/associations/association_scope.rb +126 -92
- data/lib/active_record/associations/belongs_to_association.rb +78 -27
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +9 -4
- data/lib/active_record/associations/builder/association.rb +117 -32
- data/lib/active_record/associations/builder/belongs_to.rb +135 -60
- data/lib/active_record/associations/builder/collection_association.rb +61 -54
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +120 -42
- data/lib/active_record/associations/builder/has_many.rb +10 -64
- data/lib/active_record/associations/builder/has_one.rb +19 -51
- data/lib/active_record/associations/builder/singular_association.rb +28 -18
- data/lib/active_record/associations/collection_association.rb +226 -293
- data/lib/active_record/associations/collection_proxy.rb +1067 -69
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +83 -47
- data/lib/active_record/associations/has_many_through_association.rb +98 -65
- data/lib/active_record/associations/has_one_association.rb +57 -20
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +48 -126
- data/lib/active_record/associations/join_dependency/join_base.rb +11 -12
- data/lib/active_record/associations/join_dependency/join_part.rb +35 -42
- data/lib/active_record/associations/join_dependency.rb +212 -164
- data/lib/active_record/associations/preloader/association.rb +95 -89
- data/lib/active_record/associations/preloader/through_association.rb +84 -44
- data/lib/active_record/associations/preloader.rb +123 -111
- data/lib/active_record/associations/singular_association.rb +33 -24
- data/lib/active_record/associations/through_association.rb +60 -26
- data/lib/active_record/associations.rb +1759 -1506
- data/lib/active_record/attribute_assignment.rb +60 -193
- data/lib/active_record/attribute_decorators.rb +90 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +55 -8
- data/lib/active_record/attribute_methods/dirty.rb +113 -74
- data/lib/active_record/attribute_methods/primary_key.rb +106 -77
- data/lib/active_record/attribute_methods/query.rb +8 -5
- data/lib/active_record/attribute_methods/read.rb +63 -114
- data/lib/active_record/attribute_methods/serialization.rb +60 -90
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +69 -43
- data/lib/active_record/attribute_methods/write.rb +43 -45
- data/lib/active_record/attribute_methods.rb +366 -149
- data/lib/active_record/attributes.rb +266 -0
- data/lib/active_record/autosave_association.rb +312 -225
- data/lib/active_record/base.rb +114 -505
- data/lib/active_record/callbacks.rb +145 -67
- data/lib/active_record/coders/json.rb +15 -0
- data/lib/active_record/coders/yaml_column.rb +32 -23
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +883 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +16 -2
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +350 -200
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +150 -65
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +146 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +477 -284
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +95 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1100 -310
- data/lib/active_record/connection_adapters/abstract/transaction.rb +283 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +450 -118
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +657 -446
- data/lib/active_record/connection_adapters/column.rb +50 -255
- data/lib/active_record/connection_adapters/connection_specification.rb +287 -0
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -210
- data/lib/active_record/connection_adapters/postgresql/column.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +163 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +56 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +111 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +168 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +206 -0
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +774 -0
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +620 -1080
- data/lib/active_record/connection_adapters/schema_cache.rb +85 -36
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -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 +106 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +545 -27
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +145 -0
- data/lib/active_record/core.rb +559 -0
- data/lib/active_record/counter_cache.rb +200 -105
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +107 -69
- data/lib/active_record/enum.rb +244 -0
- data/lib/active_record/errors.rb +245 -60
- data/lib/active_record/explain.rb +35 -71
- data/lib/active_record/explain_registry.rb +32 -0
- data/lib/active_record/explain_subscriber.rb +18 -9
- data/lib/active_record/fixture_set/file.rb +82 -0
- data/lib/active_record/fixtures.rb +418 -275
- data/lib/active_record/gem_version.rb +17 -0
- data/lib/active_record/inheritance.rb +209 -100
- data/lib/active_record/integration.rb +116 -21
- data/lib/active_record/internal_metadata.rb +45 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +9 -1
- data/lib/active_record/locking/optimistic.rb +107 -94
- data/lib/active_record/locking/pessimistic.rb +20 -8
- data/lib/active_record/log_subscriber.rb +99 -34
- data/lib/active_record/migration/command_recorder.rb +199 -64
- data/lib/active_record/migration/compatibility.rb +217 -0
- data/lib/active_record/migration/join_table.rb +17 -0
- data/lib/active_record/migration.rb +893 -296
- data/lib/active_record/model_schema.rb +328 -175
- data/lib/active_record/nested_attributes.rb +338 -242
- data/lib/active_record/no_touching.rb +58 -0
- data/lib/active_record/null_relation.rb +68 -0
- data/lib/active_record/persistence.rb +557 -170
- data/lib/active_record/query_cache.rb +14 -43
- data/lib/active_record/querying.rb +36 -24
- data/lib/active_record/railtie.rb +147 -52
- data/lib/active_record/railties/console_sandbox.rb +5 -4
- data/lib/active_record/railties/controller_runtime.rb +13 -6
- data/lib/active_record/railties/databases.rake +206 -488
- data/lib/active_record/readonly_attributes.rb +4 -6
- data/lib/active_record/reflection.rb +734 -228
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +249 -52
- data/lib/active_record/relation/calculations.rb +330 -284
- data/lib/active_record/relation/delegation.rb +135 -37
- data/lib/active_record/relation/finder_methods.rb +450 -287
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +193 -0
- data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder.rb +132 -43
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +1037 -221
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +48 -151
- data/lib/active_record/relation/where_clause.rb +186 -0
- data/lib/active_record/relation/where_clause_factory.rb +34 -0
- data/lib/active_record/relation.rb +451 -359
- data/lib/active_record/result.rb +129 -20
- data/lib/active_record/runtime_registry.rb +24 -0
- data/lib/active_record/sanitization.rb +164 -136
- data/lib/active_record/schema.rb +31 -19
- data/lib/active_record/schema_dumper.rb +154 -107
- data/lib/active_record/schema_migration.rb +56 -0
- data/lib/active_record/scoping/default.rb +108 -98
- data/lib/active_record/scoping/named.rb +125 -112
- data/lib/active_record/scoping.rb +77 -123
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +10 -6
- data/lib/active_record/statement_cache.rb +121 -0
- data/lib/active_record/store.rb +175 -16
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +82 -0
- data/lib/active_record/tasks/database_tasks.rb +337 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +143 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +83 -0
- data/lib/active_record/timestamp.rb +80 -41
- data/lib/active_record/touch_later.rb +64 -0
- data/lib/active_record/transactions.rb +240 -119
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +136 -0
- data/lib/active_record/type/date.rb +9 -0
- data/lib/active_record/type/date_time.rb +9 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
- 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 +71 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +21 -0
- data/lib/active_record/type/type_map.rb +62 -0
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +79 -0
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +35 -18
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +68 -0
- data/lib/active_record/validations/uniqueness.rb +133 -75
- data/lib/active_record/validations.rb +53 -43
- data/lib/active_record/version.rb +7 -7
- data/lib/active_record.rb +89 -57
- 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/migration_generator.rb +61 -8
- 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.tt +46 -0
- data/lib/rails/generators/active_record/migration.rb +28 -8
- data/lib/rails/generators/active_record/model/model_generator.rb +23 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +13 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +1 -1
- data/lib/rails/generators/active_record.rb +10 -16
- metadata +141 -62
- data/examples/associations.png +0 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
- data/lib/active_record/associations/join_helper.rb +0 -55
- 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_and_belongs_to_many.rb +0 -60
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -15
- 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_methods/deprecated_underscore_read.rb +0 -32
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -441
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
- data/lib/active_record/dynamic_finder_match.rb +0 -68
- data/lib/active_record/dynamic_scope_match.rb +0 -23
- data/lib/active_record/fixtures/file.rb +0 -65
- data/lib/active_record/identity_map.rb +0 -162
- data/lib/active_record/observer.rb +0 -121
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -203
- data/lib/active_record/session_store.rb +0 -360
- data/lib/active_record/test_case.rb +0 -73
- data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -34
- data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -12
- data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
- data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,13 +1,13 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
|
-
# = Active Record Callbacks
|
4
|
+
# = Active Record \Callbacks
|
5
5
|
#
|
6
|
-
# Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
|
6
|
+
# \Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
|
7
7
|
# before or after an alteration of the object state. This can be used to make sure that associated and
|
8
|
-
# dependent objects are deleted when
|
9
|
-
# before they're validated (by overwriting +before_validation+).
|
10
|
-
# the
|
8
|
+
# dependent objects are deleted when {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] is called (by overwriting +before_destroy+) or
|
9
|
+
# to massage attributes before they're validated (by overwriting +before_validation+).
|
10
|
+
# As an example of the callbacks initiated, consider the {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] call for a new record:
|
11
11
|
#
|
12
12
|
# * (-) <tt>save</tt>
|
13
13
|
# * (-) <tt>valid</tt>
|
@@ -22,22 +22,25 @@ module ActiveRecord
|
|
22
22
|
# * (7) <tt>after_commit</tt>
|
23
23
|
#
|
24
24
|
# Also, an <tt>after_rollback</tt> callback can be configured to be triggered whenever a rollback is issued.
|
25
|
-
# Check out
|
25
|
+
# Check out ActiveRecord::Transactions for more details about <tt>after_commit</tt> and
|
26
26
|
# <tt>after_rollback</tt>.
|
27
27
|
#
|
28
|
-
#
|
28
|
+
# Additionally, an <tt>after_touch</tt> callback is triggered whenever an
|
29
|
+
# object is touched.
|
30
|
+
#
|
31
|
+
# Lastly an <tt>after_find</tt> and <tt>after_initialize</tt> callback is triggered for each object that
|
29
32
|
# is found and instantiated by a finder, with <tt>after_initialize</tt> being triggered after new objects
|
30
33
|
# are instantiated as well.
|
31
34
|
#
|
32
|
-
#
|
33
|
-
# Active Record life cycle. The sequence for calling
|
35
|
+
# There are nineteen callbacks in total, which give you immense power to react and prepare for each state in the
|
36
|
+
# Active Record life cycle. The sequence for calling {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] for an existing record is similar,
|
34
37
|
# except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback.
|
35
38
|
#
|
36
39
|
# Examples:
|
37
40
|
# class CreditCard < ActiveRecord::Base
|
38
41
|
# # Strip everything but digits, so the user can specify "555 234 34" or
|
39
|
-
# # "5552-3434"
|
40
|
-
# before_validation(:
|
42
|
+
# # "5552-3434" and both will mean "55523434"
|
43
|
+
# before_validation(on: :create) do
|
41
44
|
# self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
|
42
45
|
# end
|
43
46
|
# end
|
@@ -52,9 +55,9 @@ module ActiveRecord
|
|
52
55
|
# end
|
53
56
|
#
|
54
57
|
# class Firm < ActiveRecord::Base
|
55
|
-
# #
|
56
|
-
# before_destroy { |record| Person.
|
57
|
-
# before_destroy { |record| Client.
|
58
|
+
# # Disables access to the system, for associated clients and people when the firm is destroyed
|
59
|
+
# before_destroy { |record| Person.where(firm_id: record.id).update_all(access: 'disabled') }
|
60
|
+
# before_destroy { |record| Client.where(client_of: record.id).update_all(access: 'disabled') }
|
58
61
|
# end
|
59
62
|
#
|
60
63
|
# == Inheritable callback queues
|
@@ -85,7 +88,7 @@ module ActiveRecord
|
|
85
88
|
#
|
86
89
|
# In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
|
87
90
|
# So, use the callback macros when you want to ensure that a certain callback is called for the entire
|
88
|
-
# hierarchy, and use the regular
|
91
|
+
# hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant
|
89
92
|
# to decide whether they want to call +super+ and trigger the inherited callbacks.
|
90
93
|
#
|
91
94
|
# *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
|
@@ -95,9 +98,9 @@ module ActiveRecord
|
|
95
98
|
# == Types of callbacks
|
96
99
|
#
|
97
100
|
# There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
|
98
|
-
# inline methods (using a proc)
|
101
|
+
# inline methods (using a proc). Method references and callback objects
|
99
102
|
# are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for
|
100
|
-
# creating mix-ins)
|
103
|
+
# creating mix-ins).
|
101
104
|
#
|
102
105
|
# The method reference callbacks work by specifying a protected or private method available in the object, like this:
|
103
106
|
#
|
@@ -127,7 +130,7 @@ module ActiveRecord
|
|
127
130
|
# record.credit_card_number = decrypt(record.credit_card_number)
|
128
131
|
# end
|
129
132
|
#
|
130
|
-
# alias_method :
|
133
|
+
# alias_method :after_initialize, :after_save
|
131
134
|
#
|
132
135
|
# private
|
133
136
|
# def encrypt(value)
|
@@ -162,7 +165,7 @@ module ActiveRecord
|
|
162
165
|
# record.send("#{@attribute}=", decrypt(record.send("#{@attribute}")))
|
163
166
|
# end
|
164
167
|
#
|
165
|
-
# alias_method :
|
168
|
+
# alias_method :after_initialize, :after_save
|
166
169
|
#
|
167
170
|
# private
|
168
171
|
# def encrypt(value)
|
@@ -174,64 +177,135 @@ module ActiveRecord
|
|
174
177
|
# end
|
175
178
|
# end
|
176
179
|
#
|
177
|
-
#
|
178
|
-
#
|
180
|
+
# == <tt>before_validation*</tt> returning statements
|
181
|
+
#
|
182
|
+
# If the +before_validation+ callback throws +:abort+, the process will be
|
183
|
+
# aborted and {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] will return +false+.
|
184
|
+
# If {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] is called it will raise an ActiveRecord::RecordInvalid exception.
|
185
|
+
# Nothing will be appended to the errors object.
|
186
|
+
#
|
187
|
+
# == Canceling callbacks
|
188
|
+
#
|
189
|
+
# If a <tt>before_*</tt> callback throws +:abort+, all the later callbacks and
|
190
|
+
# the associated action are cancelled.
|
191
|
+
# Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
|
192
|
+
# methods on the model, which are called last.
|
193
|
+
#
|
194
|
+
# == Ordering callbacks
|
195
|
+
#
|
196
|
+
# Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+
|
197
|
+
# callback (+log_children+ in this case) should be executed before the children get destroyed by the
|
198
|
+
# <tt>dependent: :destroy</tt> option.
|
199
|
+
#
|
200
|
+
# Let's look at the code below:
|
179
201
|
#
|
180
202
|
# class Topic < ActiveRecord::Base
|
181
|
-
#
|
203
|
+
# has_many :children, dependent: :destroy
|
204
|
+
#
|
205
|
+
# before_destroy :log_children
|
206
|
+
#
|
207
|
+
# private
|
208
|
+
# def log_children
|
209
|
+
# # Child processing
|
210
|
+
# end
|
182
211
|
# end
|
183
212
|
#
|
184
|
-
#
|
185
|
-
#
|
213
|
+
# In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available
|
214
|
+
# because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback gets executed first.
|
215
|
+
# You can use the +prepend+ option on the +before_destroy+ callback to avoid this.
|
186
216
|
#
|
187
217
|
# class Topic < ActiveRecord::Base
|
188
|
-
#
|
189
|
-
#
|
218
|
+
# has_many :children, dependent: :destroy
|
219
|
+
#
|
220
|
+
# before_destroy :log_children, prepend: true
|
221
|
+
#
|
222
|
+
# private
|
223
|
+
# def log_children
|
224
|
+
# # Child processing
|
225
|
+
# end
|
190
226
|
# end
|
191
227
|
#
|
192
|
-
#
|
228
|
+
# This way, the +before_destroy+ gets executed before the <tt>dependent: :destroy</tt> is called, and the data is still available.
|
193
229
|
#
|
194
|
-
#
|
195
|
-
#
|
196
|
-
# ActiveRecord::RecordInvalid exception. Nothing will be appended to the errors object.
|
230
|
+
# Also, there are cases when you want several callbacks of the same type to
|
231
|
+
# be executed in order.
|
197
232
|
#
|
198
|
-
#
|
233
|
+
# For example:
|
199
234
|
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
#
|
203
|
-
#
|
235
|
+
# class Topic < ActiveRecord::Base
|
236
|
+
# has_many :children
|
237
|
+
#
|
238
|
+
# after_save :log_children
|
239
|
+
# after_save :do_something_else
|
204
240
|
#
|
205
|
-
#
|
241
|
+
# private
|
206
242
|
#
|
207
|
-
#
|
208
|
-
#
|
209
|
-
#
|
243
|
+
# def log_children
|
244
|
+
# # Child processing
|
245
|
+
# end
|
246
|
+
#
|
247
|
+
# def do_something_else
|
248
|
+
# # Something else
|
249
|
+
# end
|
250
|
+
# end
|
251
|
+
#
|
252
|
+
# In this case the +log_children+ gets executed before +do_something_else+.
|
253
|
+
# The same applies to all non-transactional callbacks.
|
254
|
+
#
|
255
|
+
# In case there are multiple transactional callbacks as seen below, the order
|
256
|
+
# is reversed.
|
257
|
+
#
|
258
|
+
# For example:
|
259
|
+
#
|
260
|
+
# class Topic < ActiveRecord::Base
|
261
|
+
# has_many :children
|
262
|
+
#
|
263
|
+
# after_commit :log_children
|
264
|
+
# after_commit :do_something_else
|
265
|
+
#
|
266
|
+
# private
|
267
|
+
#
|
268
|
+
# def log_children
|
269
|
+
# # Child processing
|
270
|
+
# end
|
271
|
+
#
|
272
|
+
# def do_something_else
|
273
|
+
# # Something else
|
274
|
+
# end
|
275
|
+
# end
|
276
|
+
#
|
277
|
+
# In this case the +do_something_else+ gets executed before +log_children+.
|
278
|
+
#
|
279
|
+
# == \Transactions
|
280
|
+
#
|
281
|
+
# The entire callback chain of a {#save}[rdoc-ref:Persistence#save], {#save!}[rdoc-ref:Persistence#save!],
|
282
|
+
# or {#destroy}[rdoc-ref:Persistence#destroy] call runs within a transaction. That includes <tt>after_*</tt> hooks.
|
283
|
+
# If everything goes fine a COMMIT is executed once the chain has been completed.
|
210
284
|
#
|
211
285
|
# If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued. You
|
212
286
|
# can also trigger a ROLLBACK raising an exception in any of the callbacks,
|
213
287
|
# including <tt>after_*</tt> hooks. Note, however, that in that case the client
|
214
|
-
# needs to be aware of it because an ordinary
|
288
|
+
# needs to be aware of it because an ordinary {#save}[rdoc-ref:Persistence#save] will raise such exception
|
215
289
|
# instead of quietly returning +false+.
|
216
290
|
#
|
217
291
|
# == Debugging callbacks
|
218
|
-
#
|
219
|
-
# The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object.
|
292
|
+
#
|
293
|
+
# The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. Active Model \Callbacks support
|
220
294
|
# <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
|
221
295
|
# defines what part of the chain the callback runs in.
|
222
|
-
#
|
223
|
-
# To find all callbacks in the before_save callback chain:
|
224
|
-
#
|
296
|
+
#
|
297
|
+
# To find all callbacks in the before_save callback chain:
|
298
|
+
#
|
225
299
|
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
|
226
|
-
#
|
300
|
+
#
|
227
301
|
# Returns an array of callback objects that form the before_save chain.
|
228
|
-
#
|
302
|
+
#
|
229
303
|
# To further check if the before_save chain contains a proc defined as <tt>rest_when_dead</tt> use the <tt>filter</tt> property of the callback object:
|
230
|
-
#
|
304
|
+
#
|
231
305
|
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
|
232
|
-
#
|
306
|
+
#
|
233
307
|
# Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.
|
234
|
-
#
|
308
|
+
#
|
235
309
|
module Callbacks
|
236
310
|
extend ActiveSupport::Concern
|
237
311
|
|
@@ -242,34 +316,38 @@ module ActiveRecord
|
|
242
316
|
:before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
|
243
317
|
]
|
244
318
|
|
245
|
-
included do
|
246
|
-
extend ActiveModel::Callbacks
|
247
|
-
include ActiveModel::Validations::Callbacks
|
248
|
-
|
249
|
-
define_model_callbacks :initialize, :find, :touch, :only => :after
|
250
|
-
define_model_callbacks :save, :create, :update, :destroy
|
251
|
-
end
|
252
|
-
|
253
319
|
def destroy #:nodoc:
|
254
|
-
|
320
|
+
@_destroy_callback_already_called ||= false
|
321
|
+
return if @_destroy_callback_already_called
|
322
|
+
@_destroy_callback_already_called = true
|
323
|
+
_run_destroy_callbacks { super }
|
324
|
+
rescue RecordNotDestroyed => e
|
325
|
+
@_association_destroy_exception = e
|
326
|
+
false
|
327
|
+
ensure
|
328
|
+
@_destroy_callback_already_called = false
|
255
329
|
end
|
256
330
|
|
257
331
|
def touch(*) #:nodoc:
|
258
|
-
|
332
|
+
_run_touch_callbacks { super }
|
333
|
+
end
|
334
|
+
|
335
|
+
def increment!(attribute, by = 1, touch: nil) # :nodoc:
|
336
|
+
touch ? _run_touch_callbacks { super } : super
|
259
337
|
end
|
260
338
|
|
261
339
|
private
|
262
340
|
|
263
|
-
def create_or_update
|
264
|
-
|
341
|
+
def create_or_update(*)
|
342
|
+
_run_save_callbacks { super }
|
265
343
|
end
|
266
344
|
|
267
|
-
def
|
268
|
-
|
345
|
+
def _create_record
|
346
|
+
_run_create_callbacks { super }
|
269
347
|
end
|
270
348
|
|
271
|
-
def
|
272
|
-
|
349
|
+
def _update_record(*)
|
350
|
+
_run_update_callbacks { super }
|
273
351
|
end
|
274
352
|
end
|
275
353
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Coders # :nodoc:
|
5
|
+
class JSON # :nodoc:
|
6
|
+
def self.dump(obj)
|
7
|
+
ActiveSupport::JSON.encode(obj)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.load(json)
|
11
|
+
ActiveSupport::JSON.decode(json) unless json.blank?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,41 +1,50 @@
|
|
1
|
-
|
2
|
-
# :stopdoc:
|
3
|
-
module Coders
|
4
|
-
class YAMLColumn
|
5
|
-
RESCUE_ERRORS = [ ArgumentError ]
|
1
|
+
# frozen_string_literal: true
|
6
2
|
|
7
|
-
|
8
|
-
RESCUE_ERRORS << Psych::SyntaxError
|
9
|
-
end
|
3
|
+
require "yaml"
|
10
4
|
|
5
|
+
module ActiveRecord
|
6
|
+
module Coders # :nodoc:
|
7
|
+
class YAMLColumn # :nodoc:
|
11
8
|
attr_accessor :object_class
|
12
9
|
|
13
|
-
def initialize(object_class = Object)
|
10
|
+
def initialize(attr_name, object_class = Object)
|
11
|
+
@attr_name = attr_name
|
14
12
|
@object_class = object_class
|
13
|
+
check_arity_of_constructor
|
15
14
|
end
|
16
15
|
|
17
16
|
def dump(obj)
|
17
|
+
return if obj.nil?
|
18
|
+
|
19
|
+
assert_valid_value(obj, action: "dump")
|
18
20
|
YAML.dump obj
|
19
21
|
end
|
20
22
|
|
21
23
|
def load(yaml)
|
22
24
|
return object_class.new if object_class != Object && yaml.nil?
|
23
|
-
return yaml unless yaml.is_a?(String) && yaml
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
return yaml unless yaml.is_a?(String) && /^---/.match?(yaml)
|
26
|
+
obj = YAML.load(yaml)
|
27
|
+
|
28
|
+
assert_valid_value(obj, action: "load")
|
29
|
+
obj ||= object_class.new if object_class != Object
|
30
|
+
|
31
|
+
obj
|
32
|
+
end
|
33
|
+
|
34
|
+
def assert_valid_value(obj, action:)
|
35
|
+
unless obj.nil? || obj.is_a?(object_class)
|
36
|
+
raise SerializationTypeMismatch,
|
37
|
+
"can't #{action} `#{@attr_name}`: was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}"
|
36
38
|
end
|
37
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def check_arity_of_constructor
|
44
|
+
load(nil)
|
45
|
+
rescue ArgumentError
|
46
|
+
raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
|
47
|
+
end
|
38
48
|
end
|
39
49
|
end
|
40
|
-
# :startdoc
|
41
50
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module CollectionCacheKey
|
5
|
+
def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
|
6
|
+
query_signature = ActiveSupport::Digest.hexdigest(collection.to_sql)
|
7
|
+
key = "#{collection.model_name.cache_key}/query-#{query_signature}"
|
8
|
+
|
9
|
+
if collection.loaded? || collection.distinct_value
|
10
|
+
size = collection.records.size
|
11
|
+
if size > 0
|
12
|
+
timestamp = collection.max_by(×tamp_column)._read_attribute(timestamp_column)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
if collection.eager_loading?
|
16
|
+
collection = collection.send(:apply_join_dependency)
|
17
|
+
end
|
18
|
+
column_type = type_for_attribute(timestamp_column)
|
19
|
+
column = connection.column_name_from_arel_node(collection.arel_attribute(timestamp_column))
|
20
|
+
select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
|
21
|
+
|
22
|
+
if collection.has_limit_or_offset?
|
23
|
+
query = collection.select("#{column} AS collection_cache_key_timestamp")
|
24
|
+
subquery_alias = "subquery_for_cache_key"
|
25
|
+
subquery_column = "#{subquery_alias}.collection_cache_key_timestamp"
|
26
|
+
subquery = query.arel.as(subquery_alias)
|
27
|
+
arel = Arel::SelectManager.new(subquery).project(select_values % subquery_column)
|
28
|
+
else
|
29
|
+
query = collection.unscope(:order)
|
30
|
+
query.select_values = [select_values % column]
|
31
|
+
arel = query.arel
|
32
|
+
end
|
33
|
+
|
34
|
+
result = connection.select_one(arel, nil)
|
35
|
+
|
36
|
+
if result.blank?
|
37
|
+
size = 0
|
38
|
+
timestamp = nil
|
39
|
+
else
|
40
|
+
size = result["size"]
|
41
|
+
timestamp = column_type.deserialize(result["timestamp"])
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
if timestamp
|
47
|
+
"#{key}-#{size}-#{timestamp.utc.to_s(cache_timestamp_format)}"
|
48
|
+
else
|
49
|
+
"#{key}-#{size}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|