activerecord 6.1.7 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1516 -1019
- data/MIT-LICENSE +1 -1
- data/README.rdoc +17 -18
- data/lib/active_record/aggregations.rb +17 -14
- data/lib/active_record/association_relation.rb +1 -11
- data/lib/active_record/associations/association.rb +50 -19
- data/lib/active_record/associations/association_scope.rb +17 -12
- data/lib/active_record/associations/belongs_to_association.rb +28 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +11 -5
- data/lib/active_record/associations/builder/belongs_to.rb +40 -14
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +6 -2
- data/lib/active_record/associations/collection_association.rb +35 -31
- data/lib/active_record/associations/collection_proxy.rb +30 -15
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +28 -18
- data/lib/active_record/associations/has_many_through_association.rb +12 -7
- data/lib/active_record/associations/has_one_association.rb +20 -10
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +26 -16
- data/lib/active_record/associations/preloader/association.rb +207 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +50 -14
- data/lib/active_record/associations/preloader.rb +50 -121
- data/lib/active_record/associations/singular_association.rb +9 -3
- data/lib/active_record/associations/through_association.rb +25 -14
- data/lib/active_record/associations.rb +423 -289
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
- data/lib/active_record/attribute_methods/dirty.rb +61 -14
- data/lib/active_record/attribute_methods/primary_key.rb +78 -26
- data/lib/active_record/attribute_methods/query.rb +31 -19
- data/lib/active_record/attribute_methods/read.rb +25 -10
- data/lib/active_record/attribute_methods/serialization.rb +194 -37
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +10 -13
- data/lib/active_record/attribute_methods.rb +121 -40
- data/lib/active_record/attributes.rb +27 -38
- data/lib/active_record/autosave_association.rb +61 -30
- data/lib/active_record/base.rb +25 -2
- data/lib/active_record/callbacks.rb +18 -34
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -46
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +96 -590
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -51
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +77 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +360 -136
- data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
- data/lib/active_record/connection_adapters/abstract_adapter.rb +622 -149
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +285 -156
- data/lib/active_record/connection_adapters/column.rb +13 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
- data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +104 -53
- data/lib/active_record/connection_adapters/pool_config.rb +20 -11
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +18 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +86 -52
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +381 -69
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +492 -230
- data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +65 -53
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +294 -102
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
- data/lib/active_record/connection_adapters.rb +9 -6
- data/lib/active_record/connection_handling.rb +107 -136
- data/lib/active_record/core.rb +194 -224
- data/lib/active_record/counter_cache.rb +46 -25
- data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
- data/lib/active_record/database_configurations/database_config.rb +21 -12
- data/lib/active_record/database_configurations/hash_config.rb +84 -16
- data/lib/active_record/database_configurations/url_config.rb +18 -12
- data/lib/active_record/database_configurations.rb +95 -59
- data/lib/active_record/delegated_type.rb +61 -15
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +224 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +151 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +172 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +92 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +96 -0
- data/lib/active_record/encryption.rb +56 -0
- data/lib/active_record/enum.rb +156 -62
- data/lib/active_record/errors.rb +171 -15
- data/lib/active_record/explain.rb +23 -3
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +70 -14
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +131 -86
- data/lib/active_record/future_result.rb +164 -0
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +81 -29
- data/lib/active_record/insert_all.rb +133 -20
- data/lib/active_record/integration.rb +11 -10
- data/lib/active_record/internal_metadata.rb +117 -33
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +36 -21
- data/lib/active_record/locking/pessimistic.rb +15 -6
- data/lib/active_record/log_subscriber.rb +52 -19
- data/lib/active_record/marshalling.rb +56 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
- data/lib/active_record/middleware/database_selector.rb +23 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +108 -13
- data/lib/active_record/migration/compatibility.rb +221 -48
- data/lib/active_record/migration/default_strategy.rb +23 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +355 -171
- data/lib/active_record/model_schema.rb +116 -97
- data/lib/active_record/nested_attributes.rb +36 -15
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/normalization.rb +159 -0
- data/lib/active_record/persistence.rb +405 -85
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +3 -21
- data/lib/active_record/query_logs.rb +174 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +29 -6
- data/lib/active_record/railtie.rb +219 -43
- data/lib/active_record/railties/controller_runtime.rb +13 -9
- data/lib/active_record/railties/databases.rake +185 -249
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +41 -3
- data/lib/active_record/reflection.rb +229 -80
- data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
- data/lib/active_record/relation/batches.rb +192 -63
- data/lib/active_record/relation/calculations.rb +211 -90
- data/lib/active_record/relation/delegation.rb +27 -13
- data/lib/active_record/relation/finder_methods.rb +108 -51
- data/lib/active_record/relation/merger.rb +22 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +27 -20
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +654 -127
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +20 -3
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +262 -120
- data/lib/active_record/result.rb +37 -11
- data/lib/active_record/runtime_registry.rb +18 -13
- data/lib/active_record/sanitization.rb +65 -20
- data/lib/active_record/schema.rb +36 -22
- data/lib/active_record/schema_dumper.rb +73 -24
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +72 -15
- data/lib/active_record/scoping/named.rb +5 -13
- data/lib/active_record/scoping.rb +65 -34
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +10 -8
- data/lib/active_record/store.rb +10 -10
- data/lib/active_record/suppressor.rb +13 -15
- data/lib/active_record/table_metadata.rb +16 -3
- data/lib/active_record/tasks/database_tasks.rb +225 -136
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
- data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +116 -96
- data/lib/active_record/timestamp.rb +28 -17
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +48 -27
- data/lib/active_record/translation.rb +3 -3
- data/lib/active_record/type/adapter_specific_registry.rb +32 -14
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +9 -5
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +4 -4
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +51 -6
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +335 -32
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/and.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -1
- data/lib/arel/nodes/bound_sql_literal.rb +61 -0
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/homogeneous_in.rb +0 -8
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +5 -0
- data/lib/arel/predications.rb +13 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +9 -6
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +16 -3
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +139 -19
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +18 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +92 -13
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -67
data/lib/active_record/errors.rb
CHANGED
@@ -7,9 +7,13 @@ module ActiveRecord
|
|
7
7
|
class ActiveRecordError < StandardError
|
8
8
|
end
|
9
9
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
10
|
+
# DEPRECATED: Previously raised when trying to use a feature in Active Record which
|
11
|
+
# requires Active Job but the gem is not present. Now raises a NameError.
|
12
|
+
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
13
|
+
DeprecatedActiveJobRequiredError = Class.new(ActiveRecordError) # :nodoc:
|
14
|
+
deprecate_constant "ActiveJobRequiredError", "ActiveRecord::DeprecatedActiveJobRequiredError",
|
15
|
+
message: "ActiveRecord::ActiveJobRequiredError has been deprecated. If Active Job is not present, a NameError will be raised instead.",
|
16
|
+
deprecator: ActiveRecord.deprecator
|
13
17
|
|
14
18
|
# Raised when the single-table inheritance mechanism fails to locate the subclass
|
15
19
|
# (for example due to improper usage of column that
|
@@ -51,10 +55,31 @@ module ActiveRecord
|
|
51
55
|
class AdapterNotFound < ActiveRecordError
|
52
56
|
end
|
53
57
|
|
58
|
+
# Superclass for all errors raised from an Active Record adapter.
|
59
|
+
class AdapterError < ActiveRecordError
|
60
|
+
def initialize(message = nil, connection_pool: nil)
|
61
|
+
@connection_pool = connection_pool
|
62
|
+
super(message)
|
63
|
+
end
|
64
|
+
|
65
|
+
attr_reader :connection_pool
|
66
|
+
end
|
67
|
+
|
54
68
|
# Raised when connection to the database could not been established (for example when
|
55
69
|
# {ActiveRecord::Base.connection=}[rdoc-ref:ConnectionHandling#connection]
|
56
70
|
# is given a +nil+ object).
|
57
|
-
class ConnectionNotEstablished <
|
71
|
+
class ConnectionNotEstablished < AdapterError
|
72
|
+
def initialize(message = nil, connection_pool: nil)
|
73
|
+
super(message, connection_pool: connection_pool)
|
74
|
+
end
|
75
|
+
|
76
|
+
def set_pool(connection_pool)
|
77
|
+
unless @connection_pool
|
78
|
+
@connection_pool = connection_pool
|
79
|
+
end
|
80
|
+
|
81
|
+
self
|
82
|
+
end
|
58
83
|
end
|
59
84
|
|
60
85
|
# Raised when a connection could not be obtained within the connection
|
@@ -63,10 +88,34 @@ module ActiveRecord
|
|
63
88
|
class ConnectionTimeoutError < ConnectionNotEstablished
|
64
89
|
end
|
65
90
|
|
91
|
+
# Raised when connection to the database could not been established because it was not
|
92
|
+
# able to connect to the host or when the authorization failed.
|
93
|
+
class DatabaseConnectionError < ConnectionNotEstablished
|
94
|
+
def initialize(message = nil)
|
95
|
+
super(message || "Database connection error")
|
96
|
+
end
|
97
|
+
|
98
|
+
class << self
|
99
|
+
def hostname_error(hostname)
|
100
|
+
DatabaseConnectionError.new(<<~MSG)
|
101
|
+
There is an issue connecting with your hostname: #{hostname}.\n
|
102
|
+
Please check your database configuration and ensure there is a valid connection to your database.
|
103
|
+
MSG
|
104
|
+
end
|
105
|
+
|
106
|
+
def username_error(username)
|
107
|
+
DatabaseConnectionError.new(<<~MSG)
|
108
|
+
There is an issue connecting to your database with your username/password, username: #{username}.\n
|
109
|
+
Please check your database configuration to ensure the username/password are valid.
|
110
|
+
MSG
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
66
115
|
# Raised when a pool was unable to get ahold of all its connections
|
67
116
|
# to perform a "group" action such as
|
68
117
|
# {ActiveRecord::Base.connection_pool.disconnect!}[rdoc-ref:ConnectionAdapters::ConnectionPool#disconnect!]
|
69
|
-
# or {ActiveRecord::Base.clear_reloadable_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_reloadable_connections!].
|
118
|
+
# or {ActiveRecord::Base.connection_handler.clear_reloadable_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_reloadable_connections!].
|
70
119
|
class ExclusiveConnectionTimeoutError < ConnectionTimeoutError
|
71
120
|
end
|
72
121
|
|
@@ -100,7 +149,7 @@ module ActiveRecord
|
|
100
149
|
end
|
101
150
|
|
102
151
|
# Raised by {ActiveRecord::Base#destroy!}[rdoc-ref:Persistence#destroy!]
|
103
|
-
# when a call to {#destroy}[rdoc-ref:Persistence#destroy
|
152
|
+
# when a call to {#destroy}[rdoc-ref:Persistence#destroy]
|
104
153
|
# would return false.
|
105
154
|
#
|
106
155
|
# begin
|
@@ -118,17 +167,36 @@ module ActiveRecord
|
|
118
167
|
end
|
119
168
|
end
|
120
169
|
|
170
|
+
# Raised when Active Record finds multiple records but only expected one.
|
171
|
+
class SoleRecordExceeded < ActiveRecordError
|
172
|
+
attr_reader :record
|
173
|
+
|
174
|
+
def initialize(record = nil)
|
175
|
+
@record = record
|
176
|
+
super "Wanted only one #{record&.name || "record"}"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
121
180
|
# Superclass for all database execution errors.
|
122
181
|
#
|
123
182
|
# Wraps the underlying database error as +cause+.
|
124
|
-
class StatementInvalid <
|
125
|
-
def initialize(message = nil, sql: nil, binds: nil)
|
126
|
-
super(message || $!&.message)
|
183
|
+
class StatementInvalid < AdapterError
|
184
|
+
def initialize(message = nil, sql: nil, binds: nil, connection_pool: nil)
|
185
|
+
super(message || $!&.message, connection_pool: connection_pool)
|
127
186
|
@sql = sql
|
128
187
|
@binds = binds
|
129
188
|
end
|
130
189
|
|
131
190
|
attr_reader :sql, :binds
|
191
|
+
|
192
|
+
def set_query(sql, binds)
|
193
|
+
unless @sql
|
194
|
+
@sql = sql
|
195
|
+
@binds = binds
|
196
|
+
end
|
197
|
+
|
198
|
+
self
|
199
|
+
end
|
132
200
|
end
|
133
201
|
|
134
202
|
# Defunct wrapper class kept for compatibility.
|
@@ -155,8 +223,13 @@ module ActiveRecord
|
|
155
223
|
foreign_key: nil,
|
156
224
|
target_table: nil,
|
157
225
|
primary_key: nil,
|
158
|
-
primary_key_column: nil
|
226
|
+
primary_key_column: nil,
|
227
|
+
query_parser: nil,
|
228
|
+
connection_pool: nil
|
159
229
|
)
|
230
|
+
@original_message = message
|
231
|
+
@query_parser = query_parser
|
232
|
+
|
160
233
|
if table
|
161
234
|
type = primary_key_column.bigint? ? :bigint : primary_key_column.type
|
162
235
|
msg = <<~EOM.squish
|
@@ -174,7 +247,24 @@ module ActiveRecord
|
|
174
247
|
if message
|
175
248
|
msg << "\nOriginal message: #{message}"
|
176
249
|
end
|
177
|
-
|
250
|
+
|
251
|
+
super(msg, sql: sql, binds: binds, connection_pool: connection_pool)
|
252
|
+
end
|
253
|
+
|
254
|
+
def set_query(sql, binds)
|
255
|
+
if @query_parser && !@sql
|
256
|
+
self.class.new(
|
257
|
+
message: @original_message,
|
258
|
+
sql: sql,
|
259
|
+
binds: binds,
|
260
|
+
connection_pool: @connection_pool,
|
261
|
+
**@query_parser.call(sql)
|
262
|
+
).tap do |exception|
|
263
|
+
exception.set_backtrace backtrace
|
264
|
+
end
|
265
|
+
else
|
266
|
+
super
|
267
|
+
end
|
178
268
|
end
|
179
269
|
end
|
180
270
|
|
@@ -190,6 +280,19 @@ module ActiveRecord
|
|
190
280
|
class RangeError < StatementInvalid
|
191
281
|
end
|
192
282
|
|
283
|
+
# Raised when a statement produces an SQL warning.
|
284
|
+
class SQLWarning < AdapterError
|
285
|
+
attr_reader :code, :level
|
286
|
+
attr_accessor :sql
|
287
|
+
|
288
|
+
def initialize(message = nil, code = nil, level = nil, sql = nil, connection_pool = nil)
|
289
|
+
super(message, connection_pool: connection_pool)
|
290
|
+
@code = code
|
291
|
+
@level = level
|
292
|
+
@sql = sql
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
193
296
|
# Raised when the number of placeholders in an SQL fragment passed to
|
194
297
|
# {ActiveRecord::Base.where}[rdoc-ref:QueryMethods#where]
|
195
298
|
# does not match the number of values supplied.
|
@@ -202,6 +305,30 @@ module ActiveRecord
|
|
202
305
|
|
203
306
|
# Raised when a given database does not exist.
|
204
307
|
class NoDatabaseError < StatementInvalid
|
308
|
+
include ActiveSupport::ActionableError
|
309
|
+
|
310
|
+
action "Create database" do
|
311
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current
|
312
|
+
end
|
313
|
+
|
314
|
+
def initialize(message = nil, connection_pool: nil)
|
315
|
+
super(message || "Database not found", connection_pool: connection_pool)
|
316
|
+
end
|
317
|
+
|
318
|
+
class << self
|
319
|
+
def db_error(db_name)
|
320
|
+
NoDatabaseError.new(<<~MSG)
|
321
|
+
We could not find your database: #{db_name}. Available database configurations can be found in config/database.yml file.
|
322
|
+
|
323
|
+
To resolve this error:
|
324
|
+
|
325
|
+
- Did you create the database for this app, or delete it? You may need to create your database.
|
326
|
+
- Has the database name changed? Check your database.yml config has the correct database name.
|
327
|
+
|
328
|
+
To create your database, run:\n\n bin/rails db:create
|
329
|
+
MSG
|
330
|
+
end
|
331
|
+
end
|
205
332
|
end
|
206
333
|
|
207
334
|
# Raised when creating a database if it exists.
|
@@ -268,7 +395,7 @@ module ActiveRecord
|
|
268
395
|
# # The system must fail on Friday so that our support department
|
269
396
|
# # won't be out of job. We silently rollback this transaction
|
270
397
|
# # without telling the user.
|
271
|
-
# raise ActiveRecord::Rollback
|
398
|
+
# raise ActiveRecord::Rollback
|
272
399
|
# end
|
273
400
|
# end
|
274
401
|
# # ActiveRecord::Rollback is the only exception that won't be passed on
|
@@ -349,13 +476,26 @@ module ActiveRecord
|
|
349
476
|
# * You are joining an existing open transaction
|
350
477
|
# * You are creating a nested (savepoint) transaction
|
351
478
|
#
|
352
|
-
# The mysql2 and postgresql adapters support setting the transaction isolation level.
|
479
|
+
# The mysql2, trilogy, and postgresql adapters support setting the transaction isolation level.
|
353
480
|
class TransactionIsolationError < ActiveRecordError
|
354
481
|
end
|
355
482
|
|
356
483
|
# TransactionRollbackError will be raised when a transaction is rolled
|
357
484
|
# back by the database due to a serialization failure or a deadlock.
|
358
485
|
#
|
486
|
+
# These exceptions should not be generally rescued in nested transaction
|
487
|
+
# blocks, because they have side-effects in the actual enclosing transaction
|
488
|
+
# and internal Active Record state. They can be rescued if you are above the
|
489
|
+
# root transaction block, though.
|
490
|
+
#
|
491
|
+
# In that case, beware of transactional tests, however, because they run test
|
492
|
+
# cases in their own umbrella transaction. If you absolutely need to handle
|
493
|
+
# these exceptions in tests please consider disabling transactional tests in
|
494
|
+
# the affected test class (<tt>self.use_transactional_tests = false</tt>).
|
495
|
+
#
|
496
|
+
# Due to the aforementioned side-effects, this exception should not be raised
|
497
|
+
# manually by users.
|
498
|
+
#
|
359
499
|
# See the following:
|
360
500
|
#
|
361
501
|
# * https://www.postgresql.org/docs/current/static/transaction-iso.html
|
@@ -363,13 +503,24 @@ module ActiveRecord
|
|
363
503
|
class TransactionRollbackError < StatementInvalid
|
364
504
|
end
|
365
505
|
|
506
|
+
# AsynchronousQueryInsideTransactionError will be raised when attempting
|
507
|
+
# to perform an asynchronous query from inside a transaction
|
508
|
+
class AsynchronousQueryInsideTransactionError < ActiveRecordError
|
509
|
+
end
|
510
|
+
|
366
511
|
# SerializationFailure will be raised when a transaction is rolled
|
367
512
|
# back by the database due to a serialization failure.
|
513
|
+
#
|
514
|
+
# This is a subclass of TransactionRollbackError, please make sure to check
|
515
|
+
# its documentation to be aware of its caveats.
|
368
516
|
class SerializationFailure < TransactionRollbackError
|
369
517
|
end
|
370
518
|
|
371
519
|
# Deadlocked will be raised when a transaction is rolled
|
372
520
|
# back by the database when a deadlock is encountered.
|
521
|
+
#
|
522
|
+
# This is a subclass of TransactionRollbackError, please make sure to check
|
523
|
+
# its documentation to be aware of its caveats.
|
373
524
|
class Deadlocked < TransactionRollbackError
|
374
525
|
end
|
375
526
|
|
@@ -398,6 +549,11 @@ module ActiveRecord
|
|
398
549
|
class AdapterTimeout < QueryAborted
|
399
550
|
end
|
400
551
|
|
552
|
+
# ConnectionFailed will be raised when the network connection to the
|
553
|
+
# database fails while sending a query or waiting for its result.
|
554
|
+
class ConnectionFailed < QueryAborted
|
555
|
+
end
|
556
|
+
|
401
557
|
# UnknownAttributeReference is raised when an unknown and potentially unsafe
|
402
558
|
# value is passed to a query method. For example, passing a non column name
|
403
559
|
# value to a relation's #order method might cause this exception.
|
@@ -409,12 +565,12 @@ module ActiveRecord
|
|
409
565
|
#
|
410
566
|
# For example, the following code would raise this exception:
|
411
567
|
#
|
412
|
-
# Post.order("
|
568
|
+
# Post.order("REPLACE(title, 'misc', 'zzzz') asc").pluck(:id)
|
413
569
|
#
|
414
570
|
# The desired result can be accomplished by wrapping the known-safe string
|
415
571
|
# in Arel.sql:
|
416
572
|
#
|
417
|
-
# Post.order(Arel.sql("
|
573
|
+
# Post.order(Arel.sql("REPLACE(title, 'misc', 'zzzz') asc")).pluck(:id)
|
418
574
|
#
|
419
575
|
# Again, such a workaround should *not* be used when passing user-provided
|
420
576
|
# values, such as request parameters or model attributes to query methods.
|
@@ -16,15 +16,15 @@ module ActiveRecord
|
|
16
16
|
|
17
17
|
# Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
|
18
18
|
# Returns a formatted string ready to be logged.
|
19
|
-
def exec_explain(queries) # :nodoc:
|
19
|
+
def exec_explain(queries, options = []) # :nodoc:
|
20
20
|
str = queries.map do |sql, binds|
|
21
|
-
msg = +"
|
21
|
+
msg = +"#{build_explain_clause(options)} #{sql}"
|
22
22
|
unless binds.empty?
|
23
23
|
msg << " "
|
24
24
|
msg << binds.map { |attr| render_bind(attr) }.inspect
|
25
25
|
end
|
26
26
|
msg << "\n"
|
27
|
-
msg <<
|
27
|
+
msg << connection_explain(sql, binds, options)
|
28
28
|
end.join("\n")
|
29
29
|
|
30
30
|
# Overriding inspect to be more human readable, especially in the console.
|
@@ -50,5 +50,25 @@ module ActiveRecord
|
|
50
50
|
|
51
51
|
[attr&.name, value]
|
52
52
|
end
|
53
|
+
|
54
|
+
def build_explain_clause(options = [])
|
55
|
+
if connection.respond_to?(:build_explain_clause, true)
|
56
|
+
connection.build_explain_clause(options)
|
57
|
+
else
|
58
|
+
"EXPLAIN for:"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def connection_explain(sql, binds, options)
|
63
|
+
if connection.method(:explain).parameters.size == 2
|
64
|
+
ActiveRecord.deprecator.warn(<<~MSG.squish)
|
65
|
+
The current database adapter, #{connection.adapter_name}, does not support explain options.
|
66
|
+
To remove this warning, the adapter must implement `build_explain_clause(options = [])`.
|
67
|
+
MSG
|
68
|
+
connection.explain(sql, binds)
|
69
|
+
else
|
70
|
+
connection.explain(sql, binds, options)
|
71
|
+
end
|
72
|
+
end
|
53
73
|
end
|
54
74
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
4
|
|
5
5
|
module ActiveRecord
|
6
6
|
# This is a thread locals registry for EXPLAIN. For example
|
@@ -8,13 +8,18 @@ module ActiveRecord
|
|
8
8
|
# ActiveRecord::ExplainRegistry.queries
|
9
9
|
#
|
10
10
|
# returns the collected queries local to the current thread.
|
11
|
-
#
|
12
|
-
# See the documentation of ActiveSupport::PerThreadRegistry
|
13
|
-
# for further details.
|
14
11
|
class ExplainRegistry # :nodoc:
|
15
|
-
|
12
|
+
class << self
|
13
|
+
delegate :reset, :collect, :collect=, :collect?, :queries, to: :instance
|
14
|
+
|
15
|
+
private
|
16
|
+
def instance
|
17
|
+
ActiveSupport::IsolatedExecutionState[:active_record_explain_registry] ||= new
|
18
|
+
end
|
19
|
+
end
|
16
20
|
|
17
|
-
attr_accessor :
|
21
|
+
attr_accessor :collect
|
22
|
+
attr_reader :queries
|
18
23
|
|
19
24
|
def initialize
|
20
25
|
reset
|
@@ -21,7 +21,7 @@ module ActiveRecord
|
|
21
21
|
# On the other hand, we want to monitor the performance of our real database
|
22
22
|
# queries, not the performance of the access to the query cache.
|
23
23
|
IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN)
|
24
|
-
EXPLAINED_SQLS = /\A\s*(with|select|update|delete|insert)\b/i
|
24
|
+
EXPLAINED_SQLS = /\A\s*(\/\*.*\*\/)?\s*(with|select|update|delete|insert)\b/i
|
25
25
|
def ignore_payload?(payload)
|
26
26
|
payload[:exception] ||
|
27
27
|
payload[:cached] ||
|
@@ -41,7 +41,7 @@ module ActiveRecord
|
|
41
41
|
@config_row ||= begin
|
42
42
|
row = raw_rows.find { |fixture_name, _| fixture_name == "_fixture" }
|
43
43
|
if row
|
44
|
-
row.last
|
44
|
+
validate_config_row(row.last)
|
45
45
|
else
|
46
46
|
{ 'model_class': nil, 'ignore': nil }
|
47
47
|
end
|
@@ -58,6 +58,20 @@ module ActiveRecord
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
def validate_config_row(data)
|
62
|
+
unless Hash === data
|
63
|
+
raise Fixture::FormatError, "Invalid `_fixture` section: `_fixture` must be a hash: #{@file}"
|
64
|
+
end
|
65
|
+
|
66
|
+
begin
|
67
|
+
data.assert_valid_keys("model_class", "ignore")
|
68
|
+
rescue ArgumentError => error
|
69
|
+
raise Fixture::FormatError, "Invalid `_fixture` section: #{error.message}: #{@file}"
|
70
|
+
end
|
71
|
+
|
72
|
+
data
|
73
|
+
end
|
74
|
+
|
61
75
|
# Validate our unmarshalled data.
|
62
76
|
def validate(data)
|
63
77
|
unless Hash === data || YAML::Omap === data
|
@@ -12,12 +12,22 @@ module ActiveRecord
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def primary_key_type
|
15
|
-
@primary_key_type ||= @model_class &&
|
15
|
+
@primary_key_type ||= @model_class && column_type(@model_class.primary_key)
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
@
|
20
|
-
|
18
|
+
def column_type(column_name)
|
19
|
+
@column_type ||= {}
|
20
|
+
return @column_type[column_name] if @column_type.key?(column_name)
|
21
|
+
|
22
|
+
@column_type[column_name] = @model_class && @model_class.type_for_attribute(column_name).type
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_column?(column_name)
|
26
|
+
column_names.include?(column_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def column_names
|
30
|
+
@column_names ||= @model_class ? @model_class.columns.map(&:name).to_set : Set.new
|
21
31
|
end
|
22
32
|
|
23
33
|
def timestamp_column_names
|
@@ -33,6 +33,33 @@ module ActiveRecord
|
|
33
33
|
def join_table
|
34
34
|
@association.through_reflection.table_name
|
35
35
|
end
|
36
|
+
|
37
|
+
def timestamp_column_names
|
38
|
+
@association.through_reflection.klass.all_timestamp_attributes_in_model
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class PrimaryKeyError < StandardError # :nodoc:
|
43
|
+
def initialize(label, association, value)
|
44
|
+
super(<<~MSG)
|
45
|
+
Unable to set #{association.name} to #{value} because the association has a
|
46
|
+
custom primary key (#{association.join_primary_key}) that does not match the
|
47
|
+
associated table's primary key (#{association.klass.primary_key}).
|
48
|
+
|
49
|
+
To fix this, change your fixture from
|
50
|
+
|
51
|
+
#{label}:
|
52
|
+
#{association.name}: #{value}
|
53
|
+
|
54
|
+
to
|
55
|
+
|
56
|
+
#{label}:
|
57
|
+
#{association.foreign_key}: **value**
|
58
|
+
|
59
|
+
where **value** is the #{association.join_primary_key} value for the
|
60
|
+
associated #{association.klass.name} record.
|
61
|
+
MSG
|
62
|
+
end
|
36
63
|
end
|
37
64
|
|
38
65
|
def initialize(fixture, table_rows:, label:, now:)
|
@@ -60,7 +87,7 @@ module ActiveRecord
|
|
60
87
|
return unless model_class
|
61
88
|
fill_timestamps
|
62
89
|
interpolate_label
|
63
|
-
generate_primary_key
|
90
|
+
model_class.composite_primary_key? ? generate_composite_primary_key : generate_primary_key
|
64
91
|
resolve_enums
|
65
92
|
resolve_sti_reflections
|
66
93
|
end
|
@@ -90,16 +117,28 @@ module ActiveRecord
|
|
90
117
|
end
|
91
118
|
|
92
119
|
def generate_primary_key
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
120
|
+
pk = model_metadata.primary_key_name
|
121
|
+
|
122
|
+
unless column_defined?(pk)
|
123
|
+
@row[pk] = ActiveRecord::FixtureSet.identify(@label, model_metadata.column_type(pk))
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def generate_composite_primary_key
|
128
|
+
composite_key = ActiveRecord::FixtureSet.composite_identify(@label, model_metadata.primary_key_name)
|
129
|
+
composite_key.each do |column, value|
|
130
|
+
next if column_defined?(column)
|
131
|
+
|
132
|
+
@row[column] = value
|
98
133
|
end
|
99
134
|
end
|
100
135
|
|
136
|
+
def column_defined?(col)
|
137
|
+
!model_metadata.has_column?(col) || @row.include?(col)
|
138
|
+
end
|
139
|
+
|
101
140
|
def resolve_enums
|
102
|
-
|
141
|
+
reflection_class.defined_enums.each do |name, values|
|
103
142
|
if @row.include?(name)
|
104
143
|
@row[name] = values.fetch(@row[name], @row[name])
|
105
144
|
end
|
@@ -115,13 +154,26 @@ module ActiveRecord
|
|
115
154
|
fk_name = association.join_foreign_key
|
116
155
|
|
117
156
|
if association.name.to_s != fk_name && value = @row.delete(association.name.to_s)
|
118
|
-
if association.polymorphic?
|
119
|
-
|
120
|
-
|
157
|
+
if association.polymorphic?
|
158
|
+
if value.sub!(/\s*\(([^)]*)\)\s*$/, "")
|
159
|
+
# support polymorphic belongs_to as "label (Type)"
|
160
|
+
@row[association.join_foreign_type] = $1
|
161
|
+
end
|
162
|
+
elsif association.join_primary_key != association.klass.primary_key
|
163
|
+
raise PrimaryKeyError.new(@label, association, value)
|
121
164
|
end
|
122
165
|
|
123
|
-
|
124
|
-
|
166
|
+
if fk_name.is_a?(Array)
|
167
|
+
composite_key = ActiveRecord::FixtureSet.composite_identify(value, fk_name)
|
168
|
+
composite_key.each do |column, value|
|
169
|
+
next if column_defined?(column)
|
170
|
+
|
171
|
+
@row[column] = value
|
172
|
+
end
|
173
|
+
else
|
174
|
+
fk_type = reflection_class.type_for_attribute(fk_name).type
|
175
|
+
@row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
|
176
|
+
end
|
125
177
|
end
|
126
178
|
when :has_many
|
127
179
|
if association.options[:through]
|
@@ -141,8 +193,12 @@ module ActiveRecord
|
|
141
193
|
|
142
194
|
targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
|
143
195
|
joins = targets.map do |target|
|
144
|
-
{ lhs_key => @row[model_metadata.primary_key_name],
|
145
|
-
|
196
|
+
join = { lhs_key => @row[model_metadata.primary_key_name],
|
197
|
+
rhs_key => ActiveRecord::FixtureSet.identify(target, column_type) }
|
198
|
+
association.timestamp_column_names.each do |col|
|
199
|
+
join[col] = @now
|
200
|
+
end
|
201
|
+
join
|
146
202
|
end
|
147
203
|
@table_rows.tables[table_name].concat(joins)
|
148
204
|
end
|
@@ -6,7 +6,7 @@ require "active_record/fixture_set/model_metadata"
|
|
6
6
|
module ActiveRecord
|
7
7
|
class FixtureSet
|
8
8
|
class TableRows # :nodoc:
|
9
|
-
def initialize(table_name, model_class:, fixtures
|
9
|
+
def initialize(table_name, model_class:, fixtures:)
|
10
10
|
@model_class = model_class
|
11
11
|
|
12
12
|
# track any join tables we need to insert later
|
@@ -15,7 +15,7 @@ module ActiveRecord
|
|
15
15
|
# ensure this table is loaded before any HABTM associations
|
16
16
|
@tables[table_name] = nil
|
17
17
|
|
18
|
-
build_table_rows_from(table_name, fixtures
|
18
|
+
build_table_rows_from(table_name, fixtures)
|
19
19
|
end
|
20
20
|
|
21
21
|
attr_reader :tables, :model_class
|
@@ -29,8 +29,8 @@ module ActiveRecord
|
|
29
29
|
end
|
30
30
|
|
31
31
|
private
|
32
|
-
def build_table_rows_from(table_name, fixtures
|
33
|
-
now =
|
32
|
+
def build_table_rows_from(table_name, fixtures)
|
33
|
+
now = ActiveRecord.default_timezone == :utc ? Time.now.utc : Time.now
|
34
34
|
|
35
35
|
@tables[table_name] = fixtures.map do |label, fixture|
|
36
36
|
TableRow.new(
|