activerecord 5.2.8.1 → 6.0.6.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +938 -573
- data/MIT-LICENSE +3 -1
- data/README.rdoc +5 -3
- data/examples/performance.rb +1 -1
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +4 -3
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +55 -19
- data/lib/active_record/associations/association_scope.rb +11 -7
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +19 -23
- data/lib/active_record/associations/collection_proxy.rb +14 -17
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -11
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +16 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +4 -4
- data/lib/active_record/associations/join_dependency.rb +47 -30
- data/lib/active_record/associations/preloader/association.rb +61 -41
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/preloader.rb +44 -33
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +21 -16
- data/lib/active_record/attribute_assignment.rb +7 -11
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -24
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -54
- data/lib/active_record/attribute_methods/serialization.rb +1 -2
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
- data/lib/active_record/attribute_methods/write.rb +17 -25
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attributes.rb +13 -1
- data/lib/active_record/autosave_association.rb +12 -14
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +6 -21
- data/lib/active_record/coders/yaml_column.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -18
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +77 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +105 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
- data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -217
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +137 -147
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +139 -26
- data/lib/active_record/core.rb +108 -67
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +78 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +44 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +144 -474
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +13 -6
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +11 -3
- data/lib/active_record/locking/optimistic.rb +14 -7
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +8 -27
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/migration/command_recorder.rb +54 -22
- data/lib/active_record/migration/compatibility.rb +79 -52
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +104 -85
- data/lib/active_record/model_schema.rb +62 -11
- data/lib/active_record/nested_attributes.rb +2 -4
- data/lib/active_record/no_touching.rb +9 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +232 -29
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +33 -21
- data/lib/active_record/railtie.rb +80 -61
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +199 -46
- data/lib/active_record/reflection.rb +51 -51
- data/lib/active_record/relation/batches.rb +13 -11
- data/lib/active_record/relation/calculations.rb +55 -49
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +23 -28
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +12 -17
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder.rb +5 -11
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +234 -69
- data/lib/active_record/relation/spawn_methods.rb +1 -2
- data/lib/active_record/relation/where_clause.rb +14 -11
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/relation.rb +326 -81
- data/lib/active_record/result.rb +30 -12
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +6 -2
- data/lib/active_record/scoping/default.rb +4 -6
- data/lib/active_record/scoping/named.rb +25 -16
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +23 -15
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +243 -0
- data/lib/active_record/timestamp.rb +39 -26
- data/lib/active_record/touch_later.rb +5 -4
- data/lib/active_record/transactions.rb +64 -73
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +0 -1
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +3 -5
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations/associated.rb +0 -1
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record.rb +10 -2
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +256 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +62 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/migration.rb +14 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +113 -26
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class DatabaseConfigurations
|
5
|
+
# A HashConfig object is created for each database configuration entry that
|
6
|
+
# is created from a hash.
|
7
|
+
#
|
8
|
+
# A hash config:
|
9
|
+
#
|
10
|
+
# { "development" => { "database" => "db_name" } }
|
11
|
+
#
|
12
|
+
# Becomes:
|
13
|
+
#
|
14
|
+
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
|
15
|
+
# @env_name="development", @spec_name="primary", @config={"database"=>"db_name"}>
|
16
|
+
#
|
17
|
+
# ==== Options
|
18
|
+
#
|
19
|
+
# * <tt>:env_name</tt> - The Rails environment, i.e. "development".
|
20
|
+
# * <tt>:spec_name</tt> - The specification name. In a standard two-tier
|
21
|
+
# database configuration this will default to "primary". In a multiple
|
22
|
+
# database three-tier database configuration this corresponds to the name
|
23
|
+
# used in the second tier, for example "primary_readonly".
|
24
|
+
# * <tt>:config</tt> - The config hash. This is the hash that contains the
|
25
|
+
# database adapter, name, and other important information for database
|
26
|
+
# connections.
|
27
|
+
class HashConfig < DatabaseConfig
|
28
|
+
attr_reader :config
|
29
|
+
|
30
|
+
def initialize(env_name, spec_name, config)
|
31
|
+
super(env_name, spec_name)
|
32
|
+
@config = config
|
33
|
+
end
|
34
|
+
|
35
|
+
# Determines whether a database configuration is for a replica / readonly
|
36
|
+
# connection. If the +replica+ key is present in the config, +replica?+ will
|
37
|
+
# return +true+.
|
38
|
+
def replica?
|
39
|
+
config["replica"]
|
40
|
+
end
|
41
|
+
|
42
|
+
# The migrations paths for a database configuration. If the
|
43
|
+
# +migrations_paths+ key is present in the config, +migrations_paths+
|
44
|
+
# will return its value.
|
45
|
+
def migrations_paths
|
46
|
+
config["migrations_paths"]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class DatabaseConfigurations
|
5
|
+
# A UrlConfig object is created for each database configuration
|
6
|
+
# entry that is created from a URL. This can either be a URL string
|
7
|
+
# or a hash with a URL in place of the config hash.
|
8
|
+
#
|
9
|
+
# A URL config:
|
10
|
+
#
|
11
|
+
# postgres://localhost/foo
|
12
|
+
#
|
13
|
+
# Becomes:
|
14
|
+
#
|
15
|
+
# #<ActiveRecord::DatabaseConfigurations::UrlConfig:0x00007fdc3238f340
|
16
|
+
# @env_name="default_env", @spec_name="primary",
|
17
|
+
# @config={"adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost"},
|
18
|
+
# @url="postgres://localhost/foo">
|
19
|
+
#
|
20
|
+
# ==== Options
|
21
|
+
#
|
22
|
+
# * <tt>:env_name</tt> - The Rails environment, ie "development".
|
23
|
+
# * <tt>:spec_name</tt> - The specification name. In a standard two-tier
|
24
|
+
# database configuration this will default to "primary". In a multiple
|
25
|
+
# database three-tier database configuration this corresponds to the name
|
26
|
+
# used in the second tier, for example "primary_readonly".
|
27
|
+
# * <tt>:url</tt> - The database URL.
|
28
|
+
# * <tt>:config</tt> - The config hash. This is the hash that contains the
|
29
|
+
# database adapter, name, and other important information for database
|
30
|
+
# connections.
|
31
|
+
class UrlConfig < DatabaseConfig
|
32
|
+
attr_reader :url, :config
|
33
|
+
|
34
|
+
def initialize(env_name, spec_name, url, config = {})
|
35
|
+
super(env_name, spec_name)
|
36
|
+
@config = build_config(config, url)
|
37
|
+
@url = url
|
38
|
+
end
|
39
|
+
|
40
|
+
def url_config? # :nodoc:
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
# Determines whether a database configuration is for a replica / readonly
|
45
|
+
# connection. If the +replica+ key is present in the config, +replica?+ will
|
46
|
+
# return +true+.
|
47
|
+
def replica?
|
48
|
+
config["replica"]
|
49
|
+
end
|
50
|
+
|
51
|
+
# The migrations paths for a database configuration. If the
|
52
|
+
# +migrations_paths+ key is present in the config, +migrations_paths+
|
53
|
+
# will return its value.
|
54
|
+
def migrations_paths
|
55
|
+
config["migrations_paths"]
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def build_url_hash(url)
|
60
|
+
if url.nil? || /^jdbc:/.match?(url)
|
61
|
+
{ "url" => url }
|
62
|
+
else
|
63
|
+
ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(url).to_hash
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def build_config(original_config, url)
|
68
|
+
hash = build_url_hash(url)
|
69
|
+
|
70
|
+
if original_config[env_name]
|
71
|
+
original_config[env_name].merge(hash)
|
72
|
+
else
|
73
|
+
original_config.merge(hash)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/database_configurations/database_config"
|
4
|
+
require "active_record/database_configurations/hash_config"
|
5
|
+
require "active_record/database_configurations/url_config"
|
6
|
+
|
7
|
+
module ActiveRecord
|
8
|
+
# ActiveRecord::DatabaseConfigurations returns an array of DatabaseConfig
|
9
|
+
# objects (either a HashConfig or UrlConfig) that are constructed from the
|
10
|
+
# application's database configuration hash or URL string.
|
11
|
+
class DatabaseConfigurations
|
12
|
+
class InvalidConfigurationError < StandardError; end
|
13
|
+
|
14
|
+
attr_reader :configurations
|
15
|
+
delegate :any?, to: :configurations
|
16
|
+
|
17
|
+
def initialize(configurations = {})
|
18
|
+
@configurations = build_configs(configurations)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Collects the configs for the environment and optionally the specification
|
22
|
+
# name passed in. To include replica configurations pass <tt>include_replicas: true</tt>.
|
23
|
+
#
|
24
|
+
# If a spec name is provided a single DatabaseConfig object will be
|
25
|
+
# returned, otherwise an array of DatabaseConfig objects will be
|
26
|
+
# returned that corresponds with the environment and type requested.
|
27
|
+
#
|
28
|
+
# ==== Options
|
29
|
+
#
|
30
|
+
# * <tt>env_name:</tt> The environment name. Defaults to +nil+ which will collect
|
31
|
+
# configs for all environments.
|
32
|
+
# * <tt>spec_name:</tt> The specification name (i.e. primary, animals, etc.). Defaults
|
33
|
+
# to +nil+.
|
34
|
+
# * <tt>include_replicas:</tt> Determines whether to include replicas in
|
35
|
+
# the returned list. Most of the time we're only iterating over the write
|
36
|
+
# connection (i.e. migrations don't need to run for the write and read connection).
|
37
|
+
# Defaults to +false+.
|
38
|
+
def configs_for(env_name: nil, spec_name: nil, include_replicas: false)
|
39
|
+
configs = env_with_configs(env_name)
|
40
|
+
|
41
|
+
unless include_replicas
|
42
|
+
configs = configs.select do |db_config|
|
43
|
+
!db_config.replica?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
if spec_name
|
48
|
+
configs.find do |db_config|
|
49
|
+
db_config.spec_name == spec_name
|
50
|
+
end
|
51
|
+
else
|
52
|
+
configs
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the config hash that corresponds with the environment
|
57
|
+
#
|
58
|
+
# If the application has multiple databases +default_hash+ will
|
59
|
+
# return the first config hash for the environment.
|
60
|
+
#
|
61
|
+
# { database: "my_db", adapter: "mysql2" }
|
62
|
+
def default_hash(env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_s)
|
63
|
+
default = find_db_config(env)
|
64
|
+
default.config if default
|
65
|
+
end
|
66
|
+
alias :[] :default_hash
|
67
|
+
|
68
|
+
# Returns a single DatabaseConfig object based on the requested environment.
|
69
|
+
#
|
70
|
+
# If the application has multiple databases +find_db_config+ will return
|
71
|
+
# the first DatabaseConfig for the environment.
|
72
|
+
def find_db_config(env)
|
73
|
+
configurations.find do |db_config|
|
74
|
+
db_config.env_name == env.to_s ||
|
75
|
+
(db_config.for_current_env? && db_config.spec_name == env.to_s)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns the DatabaseConfigurations object as a Hash.
|
80
|
+
def to_h
|
81
|
+
configs = configurations.reverse.inject({}) do |memo, db_config|
|
82
|
+
memo.merge(db_config.to_legacy_hash)
|
83
|
+
end
|
84
|
+
|
85
|
+
Hash[configs.to_a.reverse]
|
86
|
+
end
|
87
|
+
|
88
|
+
# Checks if the application's configurations are empty.
|
89
|
+
#
|
90
|
+
# Aliased to blank?
|
91
|
+
def empty?
|
92
|
+
configurations.empty?
|
93
|
+
end
|
94
|
+
alias :blank? :empty?
|
95
|
+
|
96
|
+
def each
|
97
|
+
throw_getter_deprecation(:each)
|
98
|
+
configurations.each { |config|
|
99
|
+
yield [config.env_name, config.config]
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def first
|
104
|
+
throw_getter_deprecation(:first)
|
105
|
+
config = configurations.first
|
106
|
+
[config.env_name, config.config]
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
def env_with_configs(env = nil)
|
111
|
+
if env
|
112
|
+
configurations.select { |db_config| db_config.env_name == env }
|
113
|
+
else
|
114
|
+
configurations
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def build_configs(configs)
|
119
|
+
return configs.configurations if configs.is_a?(DatabaseConfigurations)
|
120
|
+
return configs if configs.is_a?(Array)
|
121
|
+
|
122
|
+
db_configs = configs.flat_map do |env_name, config|
|
123
|
+
if config.is_a?(Hash) && config.all? { |_, v| v.is_a?(Hash) }
|
124
|
+
walk_configs(env_name.to_s, config)
|
125
|
+
else
|
126
|
+
build_db_config_from_raw_config(env_name.to_s, "primary", config)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_s
|
131
|
+
|
132
|
+
unless db_configs.find(&:for_current_env?)
|
133
|
+
db_configs << environment_url_config(current_env, "primary", {})
|
134
|
+
end
|
135
|
+
|
136
|
+
merge_db_environment_variables(current_env, db_configs.compact)
|
137
|
+
end
|
138
|
+
|
139
|
+
def walk_configs(env_name, config)
|
140
|
+
config.map do |spec_name, sub_config|
|
141
|
+
build_db_config_from_raw_config(env_name, spec_name.to_s, sub_config)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def build_db_config_from_raw_config(env_name, spec_name, config)
|
146
|
+
case config
|
147
|
+
when String
|
148
|
+
build_db_config_from_string(env_name, spec_name, config)
|
149
|
+
when Hash
|
150
|
+
build_db_config_from_hash(env_name, spec_name, config.stringify_keys)
|
151
|
+
else
|
152
|
+
raise InvalidConfigurationError, "'{ #{env_name} => #{config} }' is not a valid configuration. Expected '#{config}' to be a URL string or a Hash."
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def build_db_config_from_string(env_name, spec_name, config)
|
157
|
+
url = config
|
158
|
+
uri = URI.parse(url)
|
159
|
+
if uri.scheme
|
160
|
+
ActiveRecord::DatabaseConfigurations::UrlConfig.new(env_name, spec_name, url)
|
161
|
+
else
|
162
|
+
raise InvalidConfigurationError, "'{ #{env_name} => #{config} }' is not a valid configuration. Expected '#{config}' to be a URL string or a Hash."
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def build_db_config_from_hash(env_name, spec_name, config)
|
167
|
+
if config.has_key?("url")
|
168
|
+
url = config["url"]
|
169
|
+
config_without_url = config.dup
|
170
|
+
config_without_url.delete "url"
|
171
|
+
|
172
|
+
ActiveRecord::DatabaseConfigurations::UrlConfig.new(env_name, spec_name, url, config_without_url)
|
173
|
+
else
|
174
|
+
ActiveRecord::DatabaseConfigurations::HashConfig.new(env_name, spec_name, config)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def merge_db_environment_variables(current_env, configs)
|
179
|
+
configs.map do |config|
|
180
|
+
next config if config.url_config? || config.env_name != current_env
|
181
|
+
|
182
|
+
url_config = environment_url_config(current_env, config.spec_name, config.config)
|
183
|
+
url_config || config
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def environment_url_config(env, spec_name, config)
|
188
|
+
url = environment_value_for(spec_name)
|
189
|
+
return unless url
|
190
|
+
|
191
|
+
ActiveRecord::DatabaseConfigurations::UrlConfig.new(env, spec_name, url, config)
|
192
|
+
end
|
193
|
+
|
194
|
+
def environment_value_for(spec_name)
|
195
|
+
spec_env_key = "#{spec_name.upcase}_DATABASE_URL"
|
196
|
+
url = ENV[spec_env_key]
|
197
|
+
url ||= ENV["DATABASE_URL"] if spec_name == "primary"
|
198
|
+
url
|
199
|
+
end
|
200
|
+
|
201
|
+
def method_missing(method, *args, &blk)
|
202
|
+
case method
|
203
|
+
when :fetch
|
204
|
+
throw_getter_deprecation(method)
|
205
|
+
configs_for(env_name: args.first)
|
206
|
+
when :values
|
207
|
+
throw_getter_deprecation(method)
|
208
|
+
configurations.map(&:config)
|
209
|
+
when :[]=
|
210
|
+
throw_setter_deprecation(method)
|
211
|
+
|
212
|
+
env_name = args[0]
|
213
|
+
config = args[1]
|
214
|
+
|
215
|
+
remaining_configs = configurations.reject { |db_config| db_config.env_name == env_name }
|
216
|
+
new_config = build_configs(env_name => config)
|
217
|
+
new_configs = remaining_configs + new_config
|
218
|
+
|
219
|
+
ActiveRecord::Base.configurations = new_configs
|
220
|
+
else
|
221
|
+
raise NotImplementedError, "`ActiveRecord::Base.configurations` in Rails 6 now returns an object instead of a hash. The `#{method}` method is not supported. Please use `configs_for` or consult the documentation for supported methods."
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def throw_setter_deprecation(method)
|
226
|
+
ActiveSupport::Deprecation.warn("Setting `ActiveRecord::Base.configurations` with `#{method}` is deprecated. Use `ActiveRecord::Base.configurations=` directly to set the configurations instead.")
|
227
|
+
end
|
228
|
+
|
229
|
+
def throw_getter_deprecation(method)
|
230
|
+
ActiveSupport::Deprecation.warn("`ActiveRecord::Base.configurations` no longer returns a hash. Methods that act on the hash like `#{method}` are deprecated and will be removed in Rails 6.1. Use the `configs_for` method to collect and iterate over the database configurations.")
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
@@ -49,11 +49,11 @@ module ActiveRecord
|
|
49
49
|
|
50
50
|
attr_reader :model, :name, :attribute_names
|
51
51
|
|
52
|
-
def initialize(model,
|
52
|
+
def initialize(model, method_name)
|
53
53
|
@model = model
|
54
|
-
@name =
|
54
|
+
@name = method_name.to_s
|
55
55
|
@attribute_names = @name.match(self.class.pattern)[1].split("_and_")
|
56
|
-
@attribute_names.map! { |
|
56
|
+
@attribute_names.map! { |name| @model.attribute_aliases[name] || name }
|
57
57
|
end
|
58
58
|
|
59
59
|
def valid?
|
@@ -69,7 +69,6 @@ module ActiveRecord
|
|
69
69
|
end
|
70
70
|
|
71
71
|
private
|
72
|
-
|
73
72
|
def body
|
74
73
|
"#{finder}(#{attributes_hash})"
|
75
74
|
end
|
data/lib/active_record/enum.rb
CHANGED
@@ -31,7 +31,9 @@ module ActiveRecord
|
|
31
31
|
# as well. With the above example:
|
32
32
|
#
|
33
33
|
# Conversation.active
|
34
|
+
# Conversation.not_active
|
34
35
|
# Conversation.archived
|
36
|
+
# Conversation.not_archived
|
35
37
|
#
|
36
38
|
# Of course, you can also query them directly if the scopes don't fit your
|
37
39
|
# needs:
|
@@ -141,10 +143,7 @@ module ActiveRecord
|
|
141
143
|
end
|
142
144
|
end
|
143
145
|
|
144
|
-
|
145
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
146
|
-
protected
|
147
|
-
|
146
|
+
private
|
148
147
|
attr_reader :name, :mapping, :subtype
|
149
148
|
end
|
150
149
|
|
@@ -152,14 +151,16 @@ module ActiveRecord
|
|
152
151
|
klass = self
|
153
152
|
enum_prefix = definitions.delete(:_prefix)
|
154
153
|
enum_suffix = definitions.delete(:_suffix)
|
154
|
+
enum_scopes = definitions.delete(:_scopes)
|
155
155
|
definitions.each do |name, values|
|
156
|
+
assert_valid_enum_definition_values(values)
|
156
157
|
# statuses = { }
|
157
158
|
enum_values = ActiveSupport::HashWithIndifferentAccess.new
|
158
159
|
name = name.to_s
|
159
160
|
|
160
161
|
# def self.statuses() statuses end
|
161
162
|
detect_enum_conflict!(name, name.pluralize, true)
|
162
|
-
singleton_class.
|
163
|
+
singleton_class.define_method(name.pluralize) { enum_values }
|
163
164
|
defined_enums[name] = enum_values
|
164
165
|
|
165
166
|
detect_enum_conflict!(name, name)
|
@@ -172,6 +173,7 @@ module ActiveRecord
|
|
172
173
|
|
173
174
|
_enum_methods_module.module_eval do
|
174
175
|
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
|
176
|
+
value_method_names = []
|
175
177
|
pairs.each do |label, value|
|
176
178
|
if enum_prefix == true
|
177
179
|
prefix = "#{name}_"
|
@@ -185,6 +187,7 @@ module ActiveRecord
|
|
185
187
|
end
|
186
188
|
|
187
189
|
value_method_name = "#{prefix}#{label}#{suffix}"
|
190
|
+
value_method_names << value_method_name
|
188
191
|
enum_values[label] = value
|
189
192
|
label = label.to_s
|
190
193
|
|
@@ -197,9 +200,16 @@ module ActiveRecord
|
|
197
200
|
define_method("#{value_method_name}!") { update!(attr => value) }
|
198
201
|
|
199
202
|
# scope :active, -> { where(status: 0) }
|
200
|
-
|
201
|
-
|
203
|
+
# scope :not_active, -> { where.not(status: 0) }
|
204
|
+
if enum_scopes != false
|
205
|
+
klass.send(:detect_enum_conflict!, name, value_method_name, true)
|
206
|
+
klass.scope value_method_name, -> { where(attr => value) }
|
207
|
+
|
208
|
+
klass.send(:detect_enum_conflict!, name, "not_#{value_method_name}", true)
|
209
|
+
klass.scope "not_#{value_method_name}", -> { where.not(attr => value) }
|
210
|
+
end
|
202
211
|
end
|
212
|
+
klass.send(:detect_negative_enum_conditions!, value_method_names) if enum_scopes != false
|
203
213
|
end
|
204
214
|
enum_values.freeze
|
205
215
|
end
|
@@ -214,10 +224,24 @@ module ActiveRecord
|
|
214
224
|
end
|
215
225
|
end
|
216
226
|
|
227
|
+
def assert_valid_enum_definition_values(values)
|
228
|
+
unless values.is_a?(Hash) || values.all? { |v| v.is_a?(Symbol) } || values.all? { |v| v.is_a?(String) }
|
229
|
+
error_message = <<~MSG
|
230
|
+
Enum values #{values} must be either a hash, an array of symbols, or an array of strings.
|
231
|
+
MSG
|
232
|
+
raise ArgumentError, error_message
|
233
|
+
end
|
234
|
+
|
235
|
+
if values.is_a?(Hash) && values.keys.any?(&:blank?) || values.is_a?(Array) && values.any?(&:blank?)
|
236
|
+
raise ArgumentError, "Enum label name must not be blank."
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
217
240
|
ENUM_CONFLICT_MESSAGE = \
|
218
241
|
"You tried to define an enum named \"%{enum}\" on the model \"%{klass}\", but " \
|
219
242
|
"this will generate a %{type} method \"%{method}\", which is already defined " \
|
220
243
|
"by %{source}."
|
244
|
+
private_constant :ENUM_CONFLICT_MESSAGE
|
221
245
|
|
222
246
|
def detect_enum_conflict!(enum_name, method_name, klass_method = false)
|
223
247
|
if klass_method && dangerous_class_method?(method_name)
|
@@ -240,5 +264,18 @@ module ActiveRecord
|
|
240
264
|
source: source
|
241
265
|
}
|
242
266
|
end
|
267
|
+
|
268
|
+
def detect_negative_enum_conditions!(method_names)
|
269
|
+
return unless logger
|
270
|
+
|
271
|
+
method_names.select { |m| m.start_with?("not_") }.each do |potential_not|
|
272
|
+
inverted_form = potential_not.sub("not_", "")
|
273
|
+
if method_names.include?(inverted_form)
|
274
|
+
logger.warn "Enum element '#{potential_not}' in #{self.name} uses the prefix 'not_'." \
|
275
|
+
" This has caused a conflict with auto generated negative scopes." \
|
276
|
+
" Avoid using enum elements starting with 'not' where the positive form is also an element."
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
243
280
|
end
|
244
281
|
end
|
data/lib/active_record/errors.rb
CHANGED
@@ -49,6 +49,10 @@ module ActiveRecord
|
|
49
49
|
class ConnectionNotEstablished < ActiveRecordError
|
50
50
|
end
|
51
51
|
|
52
|
+
# Raised when a write to the database is attempted on a read only connection.
|
53
|
+
class ReadOnlyError < ActiveRecordError
|
54
|
+
end
|
55
|
+
|
52
56
|
# Raised when Active Record cannot find a record by given id or set of ids.
|
53
57
|
class RecordNotFound < ActiveRecordError
|
54
58
|
attr_reader :model, :primary_key, :id
|
@@ -64,7 +68,7 @@ module ActiveRecord
|
|
64
68
|
|
65
69
|
# Raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
|
66
70
|
# {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]
|
67
|
-
# methods when a record is invalid and
|
71
|
+
# methods when a record is invalid and cannot be saved.
|
68
72
|
class RecordNotSaved < ActiveRecordError
|
69
73
|
attr_reader :record
|
70
74
|
|
@@ -97,9 +101,13 @@ module ActiveRecord
|
|
97
101
|
#
|
98
102
|
# Wraps the underlying database error as +cause+.
|
99
103
|
class StatementInvalid < ActiveRecordError
|
100
|
-
def initialize(message = nil)
|
104
|
+
def initialize(message = nil, sql: nil, binds: nil)
|
101
105
|
super(message || $!.try(:message))
|
106
|
+
@sql = sql
|
107
|
+
@binds = binds
|
102
108
|
end
|
109
|
+
|
110
|
+
attr_reader :sql, :binds
|
103
111
|
end
|
104
112
|
|
105
113
|
# Defunct wrapper class kept for compatibility.
|
@@ -111,14 +119,14 @@ module ActiveRecord
|
|
111
119
|
class RecordNotUnique < WrappedDatabaseException
|
112
120
|
end
|
113
121
|
|
114
|
-
# Raised when a record cannot be inserted or updated because it references a non-existent record
|
122
|
+
# Raised when a record cannot be inserted or updated because it references a non-existent record,
|
123
|
+
# or when a record cannot be deleted because a parent record references it.
|
115
124
|
class InvalidForeignKey < WrappedDatabaseException
|
116
125
|
end
|
117
126
|
|
118
127
|
# Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
|
119
128
|
class MismatchedForeignKey < StatementInvalid
|
120
129
|
def initialize(
|
121
|
-
adapter = nil,
|
122
130
|
message: nil,
|
123
131
|
sql: nil,
|
124
132
|
binds: nil,
|
@@ -130,14 +138,14 @@ module ActiveRecord
|
|
130
138
|
)
|
131
139
|
if table
|
132
140
|
type = primary_key_column.bigint? ? :bigint : primary_key_column.type
|
133
|
-
msg =
|
141
|
+
msg = <<~EOM.squish
|
134
142
|
Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
|
135
143
|
which has type `#{primary_key_column.sql_type}`.
|
136
144
|
To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
|
137
145
|
(For example `t.#{type} :#{foreign_key}`).
|
138
146
|
EOM
|
139
147
|
else
|
140
|
-
msg =
|
148
|
+
msg = <<~EOM.squish
|
141
149
|
There is a mismatch between the foreign key and primary key column types.
|
142
150
|
Verify that the foreign key column type and the primary key of the associated table match types.
|
143
151
|
EOM
|
@@ -145,7 +153,7 @@ module ActiveRecord
|
|
145
153
|
if message
|
146
154
|
msg << "\nOriginal message: #{message}"
|
147
155
|
end
|
148
|
-
super(msg)
|
156
|
+
super(msg, sql: sql, binds: binds)
|
149
157
|
end
|
150
158
|
end
|
151
159
|
|
@@ -18,7 +18,7 @@ module ActiveRecord
|
|
18
18
|
# Returns a formatted string ready to be logged.
|
19
19
|
def exec_explain(queries) # :nodoc:
|
20
20
|
str = queries.map do |sql, binds|
|
21
|
-
msg = "EXPLAIN for: #{sql}"
|
21
|
+
msg = +"EXPLAIN for: #{sql}"
|
22
22
|
unless binds.empty?
|
23
23
|
msg << " "
|
24
24
|
msg << binds.map { |attr| render_bind(attr) }.inspect
|
@@ -36,7 +36,6 @@ module ActiveRecord
|
|
36
36
|
end
|
37
37
|
|
38
38
|
private
|
39
|
-
|
40
39
|
def render_bind(attr)
|
41
40
|
value = if attr.type.binary? && attr.value
|
42
41
|
"<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class FixtureSet
|
5
|
+
class ModelMetadata # :nodoc:
|
6
|
+
def initialize(model_class)
|
7
|
+
@model_class = model_class
|
8
|
+
end
|
9
|
+
|
10
|
+
def primary_key_name
|
11
|
+
@primary_key_name ||= @model_class && @model_class.primary_key
|
12
|
+
end
|
13
|
+
|
14
|
+
def primary_key_type
|
15
|
+
@primary_key_type ||= @model_class && @model_class.type_for_attribute(@model_class.primary_key).type
|
16
|
+
end
|
17
|
+
|
18
|
+
def has_primary_key_column?
|
19
|
+
@has_primary_key_column ||= primary_key_name &&
|
20
|
+
@model_class.columns.any? { |col| col.name == primary_key_name }
|
21
|
+
end
|
22
|
+
|
23
|
+
def timestamp_column_names
|
24
|
+
@timestamp_column_names ||=
|
25
|
+
%w(created_at created_on updated_at updated_on) & @model_class.column_names
|
26
|
+
end
|
27
|
+
|
28
|
+
def inheritance_column_name
|
29
|
+
@inheritance_column_name ||= @model_class && @model_class.inheritance_column
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# NOTE: This class has to be defined in compact style in
|
4
|
+
# order for rendering context subclassing to work correctly.
|
5
|
+
class ActiveRecord::FixtureSet::RenderContext # :nodoc:
|
6
|
+
def self.create_subclass
|
7
|
+
Class.new(ActiveRecord::FixtureSet.context_class) do
|
8
|
+
def get_binding
|
9
|
+
binding()
|
10
|
+
end
|
11
|
+
|
12
|
+
def binary(path)
|
13
|
+
%(!!binary "#{Base64.strict_encode64(File.read(path, mode: 'rb'))}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|