activerecord 4.2.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +612 -971
- data/MIT-LICENSE +4 -2
- data/README.rdoc +13 -12
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +267 -248
- data/lib/active_record/association_relation.rb +24 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +135 -56
- data/lib/active_record/associations/association_scope.rb +103 -131
- data/lib/active_record/associations/belongs_to_association.rb +67 -54
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +27 -40
- data/lib/active_record/associations/builder/belongs_to.rb +69 -55
- data/lib/active_record/associations/builder/collection_association.rb +10 -29
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +60 -70
- data/lib/active_record/associations/builder/has_many.rb +8 -4
- data/lib/active_record/associations/builder/has_one.rb +46 -5
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +138 -274
- data/lib/active_record/associations/collection_proxy.rb +252 -151
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +35 -83
- data/lib/active_record/associations/has_many_through_association.rb +62 -80
- data/lib/active_record/associations/has_one_association.rb +62 -49
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -80
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/join_dependency.rb +138 -162
- data/lib/active_record/associations/preloader/association.rb +90 -119
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +92 -94
- data/lib/active_record/associations/singular_association.rb +18 -45
- data/lib/active_record/associations/through_association.rb +48 -23
- data/lib/active_record/associations.rb +1737 -1596
- data/lib/active_record/attribute_assignment.rb +56 -183
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +15 -5
- data/lib/active_record/attribute_methods/dirty.rb +174 -134
- data/lib/active_record/attribute_methods/primary_key.rb +91 -83
- data/lib/active_record/attribute_methods/query.rb +6 -5
- data/lib/active_record/attribute_methods/read.rb +20 -76
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
- data/lib/active_record/attribute_methods/write.rb +33 -55
- data/lib/active_record/attribute_methods.rb +124 -143
- data/lib/active_record/attributes.rb +214 -74
- data/lib/active_record/autosave_association.rb +115 -46
- data/lib/active_record/base.rb +60 -49
- data/lib/active_record/callbacks.rb +100 -74
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -290
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +247 -108
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +366 -227
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +706 -222
- data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -87
- data/lib/active_record/connection_adapters/abstract_adapter.rb +468 -194
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +535 -597
- data/lib/active_record/connection_adapters/column.rb +56 -43
- data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -195
- data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +65 -115
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +474 -286
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -363
- data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +288 -359
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +176 -41
- data/lib/active_record/core.rb +266 -233
- data/lib/active_record/counter_cache.rb +68 -50
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +79 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +164 -88
- data/lib/active_record/errors.rb +189 -53
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +226 -495
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +158 -112
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +123 -29
- data/lib/active_record/internal_metadata.rb +53 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +91 -98
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +76 -33
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +177 -90
- data/lib/active_record/migration/compatibility.rb +244 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +634 -288
- data/lib/active_record/model_schema.rb +314 -112
- data/lib/active_record/nested_attributes.rb +266 -214
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +559 -124
- data/lib/active_record/query_cache.rb +19 -23
- data/lib/active_record/querying.rb +43 -29
- data/lib/active_record/railtie.rb +148 -47
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +338 -202
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +460 -299
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +207 -55
- data/lib/active_record/relation/calculations.rb +269 -248
- data/lib/active_record/relation/delegation.rb +70 -80
- data/lib/active_record/relation/finder_methods.rb +279 -255
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +83 -69
- data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +116 -92
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +574 -391
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -16
- data/lib/active_record/relation/where_clause.rb +190 -0
- data/lib/active_record/relation/where_clause_factory.rb +33 -0
- data/lib/active_record/relation.rb +518 -340
- data/lib/active_record/result.rb +79 -42
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +144 -121
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +112 -93
- data/lib/active_record/schema_migration.rb +24 -20
- data/lib/active_record/scoping/default.rb +101 -84
- data/lib/active_record/scoping/named.rb +86 -33
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +73 -36
- data/lib/active_record/store.rb +127 -42
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +75 -0
- data/lib/active_record/tasks/database_tasks.rb +309 -99
- data/lib/active_record/tasks/mysql_database_tasks.rb +58 -88
- data/lib/active_record/tasks/postgresql_database_tasks.rb +82 -31
- data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +86 -40
- data/lib/active_record/touch_later.rb +66 -0
- data/lib/active_record/transactions.rb +215 -139
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +129 -0
- data/lib/active_record/type/date.rb +4 -41
- data/lib/active_record/type/date_time.rb +4 -38
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
- 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 +30 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type.rb +78 -23
- data/lib/active_record/type_caster/connection.rb +34 -0
- data/lib/active_record/type_caster/map.rb +20 -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 +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +43 -46
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +43 -21
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +51 -0
- 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 +42 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
- data/lib/rails/generators/active_record/migration.rb +31 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +166 -60
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -149
- data/lib/active_record/attribute_set/builder.rb +0 -86
- data/lib/active_record/attribute_set.rb +0 -77
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -30
- data/lib/active_record/type/decimal.rb +0 -40
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -55
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -36
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -101
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,31 +1,77 @@
|
|
1
|
-
|
2
|
-
require 'set'
|
3
|
-
require 'bigdecimal'
|
4
|
-
require 'bigdecimal/util'
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
3
|
module ActiveRecord
|
7
4
|
module ConnectionAdapters #:nodoc:
|
8
5
|
# Abstract representation of an index definition on a table. Instances of
|
9
6
|
# this type are typically created and returned by methods in database
|
10
|
-
# adapters. e.g. ActiveRecord::ConnectionAdapters::
|
11
|
-
class IndexDefinition
|
7
|
+
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
|
8
|
+
class IndexDefinition # :nodoc:
|
9
|
+
attr_reader :table, :name, :unique, :columns, :lengths, :orders, :opclasses, :where, :type, :using, :comment
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
table, name,
|
13
|
+
unique = false,
|
14
|
+
columns = [],
|
15
|
+
lengths: {},
|
16
|
+
orders: {},
|
17
|
+
opclasses: {},
|
18
|
+
where: nil,
|
19
|
+
type: nil,
|
20
|
+
using: nil,
|
21
|
+
comment: nil
|
22
|
+
)
|
23
|
+
@table = table
|
24
|
+
@name = name
|
25
|
+
@unique = unique
|
26
|
+
@columns = columns
|
27
|
+
@lengths = concise_options(lengths)
|
28
|
+
@orders = concise_options(orders)
|
29
|
+
@opclasses = concise_options(opclasses)
|
30
|
+
@where = where
|
31
|
+
@type = type
|
32
|
+
@using = using
|
33
|
+
@comment = comment
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def concise_options(options)
|
38
|
+
if columns.size == options.size && options.values.uniq.size == 1
|
39
|
+
options.values.first
|
40
|
+
else
|
41
|
+
options
|
42
|
+
end
|
43
|
+
end
|
12
44
|
end
|
13
45
|
|
14
46
|
# Abstract representation of a column definition. Instances of this type
|
15
47
|
# are typically created by methods in TableDefinition, and added to the
|
16
48
|
# +columns+ attribute of said TableDefinition object, in order to be used
|
17
49
|
# for generating a number of table creation or table changing SQL statements.
|
18
|
-
|
19
|
-
|
50
|
+
ColumnDefinition = Struct.new(:name, :type, :options, :sql_type) do # :nodoc:
|
20
51
|
def primary_key?
|
21
|
-
|
52
|
+
options[:primary_key]
|
22
53
|
end
|
23
|
-
end
|
24
54
|
|
25
|
-
|
55
|
+
[:limit, :precision, :scale, :default, :null, :collation, :comment].each do |option_name|
|
56
|
+
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
57
|
+
def #{option_name}
|
58
|
+
options[:#{option_name}]
|
59
|
+
end
|
60
|
+
|
61
|
+
def #{option_name}=(value)
|
62
|
+
options[:#{option_name}] = value
|
63
|
+
end
|
64
|
+
CODE
|
65
|
+
end
|
26
66
|
end
|
27
67
|
|
28
|
-
|
68
|
+
AddColumnDefinition = Struct.new(:column) # :nodoc:
|
69
|
+
|
70
|
+
ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
|
71
|
+
|
72
|
+
PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
|
73
|
+
|
74
|
+
ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
|
29
75
|
def name
|
30
76
|
options[:name]
|
31
77
|
end
|
@@ -50,31 +96,151 @@ module ActiveRecord
|
|
50
96
|
options[:primary_key] != default_primary_key
|
51
97
|
end
|
52
98
|
|
99
|
+
def validate?
|
100
|
+
options.fetch(:validate, true)
|
101
|
+
end
|
102
|
+
alias validated? validate?
|
103
|
+
|
104
|
+
def export_name_on_schema_dump?
|
105
|
+
!ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
|
106
|
+
end
|
107
|
+
|
108
|
+
def defined_for?(to_table: nil, **options)
|
109
|
+
(to_table.nil? || to_table.to_s == self.to_table) &&
|
110
|
+
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
111
|
+
end
|
112
|
+
|
53
113
|
private
|
54
|
-
|
55
|
-
|
114
|
+
def default_primary_key
|
115
|
+
"id"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class ReferenceDefinition # :nodoc:
|
120
|
+
def initialize(
|
121
|
+
name,
|
122
|
+
polymorphic: false,
|
123
|
+
index: true,
|
124
|
+
foreign_key: false,
|
125
|
+
type: :bigint,
|
126
|
+
**options
|
127
|
+
)
|
128
|
+
@name = name
|
129
|
+
@polymorphic = polymorphic
|
130
|
+
@index = index
|
131
|
+
@foreign_key = foreign_key
|
132
|
+
@type = type
|
133
|
+
@options = options
|
134
|
+
|
135
|
+
if polymorphic && foreign_key
|
136
|
+
raise ArgumentError, "Cannot add a foreign key to a polymorphic relation"
|
137
|
+
end
|
56
138
|
end
|
139
|
+
|
140
|
+
def add_to(table)
|
141
|
+
columns.each do |column_options|
|
142
|
+
table.column(*column_options)
|
143
|
+
end
|
144
|
+
|
145
|
+
if index
|
146
|
+
table.index(column_names, index_options)
|
147
|
+
end
|
148
|
+
|
149
|
+
if foreign_key
|
150
|
+
table.foreign_key(foreign_table_name, foreign_key_options)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
|
156
|
+
|
157
|
+
def as_options(value)
|
158
|
+
value.is_a?(Hash) ? value : {}
|
159
|
+
end
|
160
|
+
|
161
|
+
def polymorphic_options
|
162
|
+
as_options(polymorphic).merge(options.slice(:null, :first, :after))
|
163
|
+
end
|
164
|
+
|
165
|
+
def index_options
|
166
|
+
as_options(index)
|
167
|
+
end
|
168
|
+
|
169
|
+
def foreign_key_options
|
170
|
+
as_options(foreign_key).merge(column: column_name)
|
171
|
+
end
|
172
|
+
|
173
|
+
def columns
|
174
|
+
result = [[column_name, type, options]]
|
175
|
+
if polymorphic
|
176
|
+
result.unshift(["#{name}_type", :string, polymorphic_options])
|
177
|
+
end
|
178
|
+
result
|
179
|
+
end
|
180
|
+
|
181
|
+
def column_name
|
182
|
+
"#{name}_id"
|
183
|
+
end
|
184
|
+
|
185
|
+
def column_names
|
186
|
+
columns.map(&:first)
|
187
|
+
end
|
188
|
+
|
189
|
+
def foreign_table_name
|
190
|
+
foreign_key_options.fetch(:to_table) do
|
191
|
+
Base.pluralize_table_names ? name.to_s.pluralize : name
|
192
|
+
end
|
193
|
+
end
|
57
194
|
end
|
58
195
|
|
59
|
-
module
|
60
|
-
|
61
|
-
return if options.key?(:null)
|
196
|
+
module ColumnMethods
|
197
|
+
extend ActiveSupport::Concern
|
62
198
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
199
|
+
# Appends a primary key definition to the table definition.
|
200
|
+
# Can be called multiple times, but this is probably not a good idea.
|
201
|
+
def primary_key(name, type = :primary_key, **options)
|
202
|
+
column(name, type, options.merge(primary_key: true))
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# :method: column
|
207
|
+
# :call-seq: column(name, type, **options)
|
208
|
+
#
|
209
|
+
# Appends a column or columns of a specified type.
|
210
|
+
#
|
211
|
+
# t.string(:goat)
|
212
|
+
# t.string(:goat, :sheep)
|
213
|
+
#
|
214
|
+
# See TableDefinition#column
|
215
|
+
|
216
|
+
included do
|
217
|
+
define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
|
218
|
+
:float, :integer, :json, :string, :text, :time, :timestamp, :virtual
|
219
|
+
|
220
|
+
alias :numeric :decimal
|
221
|
+
end
|
222
|
+
|
223
|
+
class_methods do
|
224
|
+
private def define_column_methods(*column_types) # :nodoc:
|
225
|
+
column_types.each do |column_type|
|
226
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
227
|
+
def #{column_type}(*names, **options)
|
228
|
+
raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
|
229
|
+
names.each { |name| column(name, :#{column_type}, options) }
|
230
|
+
end
|
231
|
+
RUBY
|
232
|
+
end
|
233
|
+
end
|
68
234
|
end
|
69
235
|
end
|
70
236
|
|
71
237
|
# Represents the schema of an SQL table in an abstract way. This class
|
72
238
|
# provides methods for manipulating the schema representation.
|
73
239
|
#
|
74
|
-
# Inside migration files, the +t+ object in
|
240
|
+
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
|
75
241
|
# is actually of this type:
|
76
242
|
#
|
77
|
-
# class SomeMigration < ActiveRecord::Migration
|
243
|
+
# class SomeMigration < ActiveRecord::Migration[5.0]
|
78
244
|
# def up
|
79
245
|
# create_table :foo do |t|
|
80
246
|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
|
@@ -86,124 +252,65 @@ module ActiveRecord
|
|
86
252
|
# end
|
87
253
|
# end
|
88
254
|
#
|
89
|
-
# The table definitions
|
90
|
-
# The Columns are stored as a ColumnDefinition in the +columns+ attribute.
|
91
255
|
class TableDefinition
|
92
|
-
include
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
256
|
+
include ColumnMethods
|
257
|
+
|
258
|
+
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
|
259
|
+
|
260
|
+
def initialize(
|
261
|
+
conn,
|
262
|
+
name,
|
263
|
+
temporary: false,
|
264
|
+
if_not_exists: false,
|
265
|
+
options: nil,
|
266
|
+
as: nil,
|
267
|
+
comment: nil,
|
268
|
+
**
|
269
|
+
)
|
270
|
+
@conn = conn
|
100
271
|
@columns_hash = {}
|
101
|
-
@indexes =
|
102
|
-
@
|
272
|
+
@indexes = []
|
273
|
+
@foreign_keys = []
|
274
|
+
@primary_keys = nil
|
103
275
|
@temporary = temporary
|
276
|
+
@if_not_exists = if_not_exists
|
104
277
|
@options = options
|
105
278
|
@as = as
|
106
279
|
@name = name
|
280
|
+
@comment = comment
|
107
281
|
end
|
108
282
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
# Can be called multiple times, but this is probably not a good idea.
|
113
|
-
def primary_key(name, type = :primary_key, options = {})
|
114
|
-
column(name, type, options.merge(:primary_key => true))
|
283
|
+
def primary_keys(name = nil) # :nodoc:
|
284
|
+
@primary_keys = PrimaryKeyDefinition.new(name) if name
|
285
|
+
@primary_keys
|
115
286
|
end
|
116
287
|
|
288
|
+
# Returns an array of ColumnDefinition objects for the columns of the table.
|
289
|
+
def columns; @columns_hash.values; end
|
290
|
+
|
117
291
|
# Returns a ColumnDefinition for the column with name +name+.
|
118
292
|
def [](name)
|
119
293
|
@columns_hash[name.to_s]
|
120
294
|
end
|
121
295
|
|
122
296
|
# Instantiates a new column for the table.
|
123
|
-
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
# <tt>:datetime</tt>, <tt>:time</tt>, <tt>:date</tt>,
|
128
|
-
# <tt>:binary</tt>, <tt>:boolean</tt>.
|
129
|
-
#
|
130
|
-
# You may use a type not in this list as long as it is supported by your
|
131
|
-
# database (for example, "polygon" in MySQL), but this will not be database
|
132
|
-
# agnostic and should usually be avoided.
|
133
|
-
#
|
134
|
-
# Available options are (none of these exists by default):
|
135
|
-
# * <tt>:limit</tt> -
|
136
|
-
# Requests a maximum column length. This is number of characters for <tt>:string</tt> and
|
137
|
-
# <tt>:text</tt> columns and number of bytes for <tt>:binary</tt> and <tt>:integer</tt> columns.
|
138
|
-
# * <tt>:default</tt> -
|
139
|
-
# The column's default value. Use nil for NULL.
|
140
|
-
# * <tt>:null</tt> -
|
141
|
-
# Allows or disallows +NULL+ values in the column. This option could
|
142
|
-
# have been named <tt>:null_allowed</tt>.
|
143
|
-
# * <tt>:precision</tt> -
|
144
|
-
# Specifies the precision for a <tt>:decimal</tt> column.
|
145
|
-
# * <tt>:scale</tt> -
|
146
|
-
# Specifies the scale for a <tt>:decimal</tt> column.
|
297
|
+
# See {connection.add_column}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_column]
|
298
|
+
# for available options.
|
299
|
+
#
|
300
|
+
# Additional options are:
|
147
301
|
# * <tt>:index</tt> -
|
148
302
|
# Create an index for the column. Can be either <tt>true</tt> or an options hash.
|
149
303
|
#
|
150
|
-
# Note: The precision is the total number of significant digits
|
151
|
-
# and the scale is the number of digits that can be stored following
|
152
|
-
# the decimal point. For example, the number 123.45 has a precision of 5
|
153
|
-
# and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
|
154
|
-
# range from -999.99 to 999.99.
|
155
|
-
#
|
156
|
-
# Please be aware of different RDBMS implementations behavior with
|
157
|
-
# <tt>:decimal</tt> columns:
|
158
|
-
# * The SQL standard says the default scale should be 0, <tt>:scale</tt> <=
|
159
|
-
# <tt>:precision</tt>, and makes no comments about the requirements of
|
160
|
-
# <tt>:precision</tt>.
|
161
|
-
# * MySQL: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..30].
|
162
|
-
# Default is (10,0).
|
163
|
-
# * PostgreSQL: <tt>:precision</tt> [1..infinity],
|
164
|
-
# <tt>:scale</tt> [0..infinity]. No default.
|
165
|
-
# * SQLite2: Any <tt>:precision</tt> and <tt>:scale</tt> may be used.
|
166
|
-
# Internal storage as strings. No default.
|
167
|
-
# * SQLite3: No restrictions on <tt>:precision</tt> and <tt>:scale</tt>,
|
168
|
-
# but the maximum supported <tt>:precision</tt> is 16. No default.
|
169
|
-
# * Oracle: <tt>:precision</tt> [1..38], <tt>:scale</tt> [-84..127].
|
170
|
-
# Default is (38,0).
|
171
|
-
# * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
|
172
|
-
# Default unknown.
|
173
|
-
# * SqlServer?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
|
174
|
-
# Default (38,0).
|
175
|
-
#
|
176
304
|
# This method returns <tt>self</tt>.
|
177
305
|
#
|
178
306
|
# == Examples
|
179
|
-
# # Assuming +td+ is an instance of TableDefinition
|
180
|
-
# td.column(:granted, :boolean)
|
181
|
-
# # granted BOOLEAN
|
182
|
-
#
|
183
|
-
# td.column(:picture, :binary, limit: 2.megabytes)
|
184
|
-
# # => picture BLOB(2097152)
|
185
307
|
#
|
186
|
-
#
|
187
|
-
#
|
188
|
-
#
|
189
|
-
# td.column(:bill_gates_money, :decimal, precision: 15, scale: 2)
|
190
|
-
# # => bill_gates_money DECIMAL(15,2)
|
191
|
-
#
|
192
|
-
# td.column(:sensor_reading, :decimal, precision: 30, scale: 20)
|
193
|
-
# # => sensor_reading DECIMAL(30,20)
|
194
|
-
#
|
195
|
-
# # While <tt>:scale</tt> defaults to zero on most databases, it
|
196
|
-
# # probably wouldn't hurt to include it.
|
197
|
-
# td.column(:huge_integer, :decimal, precision: 30)
|
198
|
-
# # => huge_integer DECIMAL(30)
|
199
|
-
#
|
200
|
-
# # Defines a column with a database-specific type.
|
201
|
-
# td.column(:foo, 'polygon')
|
202
|
-
# # => foo polygon
|
308
|
+
# # Assuming +td+ is an instance of TableDefinition
|
309
|
+
# td.column(:granted, :boolean, index: true)
|
203
310
|
#
|
204
311
|
# == Short-hand examples
|
205
312
|
#
|
206
|
-
# Instead of calling
|
313
|
+
# Instead of calling #column directly, you can also work with the short-hand definitions for the default types.
|
207
314
|
# They use the type as the method name instead of as a parameter and allow for multiple columns to be defined
|
208
315
|
# in a single statement.
|
209
316
|
#
|
@@ -235,7 +342,8 @@ module ActiveRecord
|
|
235
342
|
# TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
|
236
343
|
# column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of
|
237
344
|
# options, these will be used when creating the <tt>_type</tt> column. The <tt>:index</tt> option
|
238
|
-
# will also create an index, similar to calling
|
345
|
+
# will also create an index, similar to calling {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index].
|
346
|
+
# So what can be written like this:
|
239
347
|
#
|
240
348
|
# create_table :taggings do |t|
|
241
349
|
# t.integer :tag_id, :tagger_id, :taggable_id
|
@@ -249,15 +357,20 @@ module ActiveRecord
|
|
249
357
|
#
|
250
358
|
# create_table :taggings do |t|
|
251
359
|
# t.references :tag, index: { name: 'index_taggings_on_tag_id' }
|
252
|
-
# t.references :tagger, polymorphic: true
|
253
|
-
# t.references :taggable, polymorphic: { default: 'Photo' }
|
360
|
+
# t.references :tagger, polymorphic: true
|
361
|
+
# t.references :taggable, polymorphic: { default: 'Photo' }, index: false
|
254
362
|
# end
|
255
|
-
def column(name, type, options
|
363
|
+
def column(name, type, **options)
|
256
364
|
name = name.to_s
|
257
|
-
type = type.to_sym
|
258
|
-
|
259
|
-
|
260
|
-
|
365
|
+
type = type.to_sym if type
|
366
|
+
options = options.dup
|
367
|
+
|
368
|
+
if @columns_hash[name]
|
369
|
+
if @columns_hash[name].primary_key?
|
370
|
+
raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
|
371
|
+
else
|
372
|
+
raise ArgumentError, "you can't define an already defined column '#{name}'."
|
373
|
+
end
|
261
374
|
end
|
262
375
|
|
263
376
|
index_options = options.delete(:index)
|
@@ -266,89 +379,79 @@ module ActiveRecord
|
|
266
379
|
self
|
267
380
|
end
|
268
381
|
|
382
|
+
# remove the column +name+ from the table.
|
383
|
+
# remove_column(:account_id)
|
269
384
|
def remove_column(name)
|
270
385
|
@columns_hash.delete name.to_s
|
271
386
|
end
|
272
387
|
|
273
|
-
[:string, :text, :integer, :bigint, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
|
274
|
-
define_method column_type do |*args|
|
275
|
-
options = args.extract_options!
|
276
|
-
column_names = args
|
277
|
-
column_names.each { |name| column(name, column_type, options) }
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
388
|
# Adds index options to the indexes hash, keyed by column name
|
282
389
|
# This is primarily used to track indexes that need to be created after the table
|
283
390
|
#
|
284
391
|
# index(:account_id, name: 'index_projects_on_account_id')
|
285
392
|
def index(column_name, options = {})
|
286
|
-
indexes[column_name
|
393
|
+
indexes << [column_name, options]
|
394
|
+
end
|
395
|
+
|
396
|
+
def foreign_key(table_name, options = {}) # :nodoc:
|
397
|
+
foreign_keys << [table_name, options]
|
287
398
|
end
|
288
399
|
|
289
400
|
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
|
290
|
-
# <tt>:updated_at</tt> to the table. See SchemaStatements#add_timestamps
|
401
|
+
# <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
291
402
|
#
|
292
403
|
# t.timestamps null: false
|
293
|
-
def timestamps(
|
294
|
-
options =
|
295
|
-
|
404
|
+
def timestamps(**options)
|
405
|
+
options[:null] = false if options[:null].nil?
|
406
|
+
|
407
|
+
if !options.key?(:precision) && @conn.supports_datetime_with_precision?
|
408
|
+
options[:precision] = 6
|
409
|
+
end
|
410
|
+
|
296
411
|
column(:created_at, :datetime, options)
|
297
412
|
column(:updated_at, :datetime, options)
|
298
413
|
end
|
299
414
|
|
300
|
-
# Adds a reference.
|
301
|
-
# <tt>references</tt> and <tt>belongs_to</tt> are acceptable. The reference column will be an +integer+
|
302
|
-
# by default, the <tt>:type</tt> option can be used to specify a different type.
|
415
|
+
# Adds a reference.
|
303
416
|
#
|
304
417
|
# t.references(:user)
|
305
|
-
# t.
|
306
|
-
# t.belongs_to(:supplier,
|
418
|
+
# t.belongs_to(:supplier, foreign_key: true)
|
419
|
+
# t.belongs_to(:supplier, foreign_key: true, type: :integer)
|
307
420
|
#
|
308
|
-
# See SchemaStatements#add_reference
|
309
|
-
def references(*args)
|
310
|
-
|
311
|
-
|
312
|
-
index_options = options.delete(:index)
|
313
|
-
type = options.delete(:type) || :integer
|
314
|
-
args.each do |col|
|
315
|
-
column("#{col}_id", type, options)
|
316
|
-
column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
|
317
|
-
index(polymorphic ? %w(type id).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
|
421
|
+
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
|
422
|
+
def references(*args, **options)
|
423
|
+
args.each do |ref_name|
|
424
|
+
ReferenceDefinition.new(ref_name, options).add_to(self)
|
318
425
|
end
|
319
426
|
end
|
320
427
|
alias :belongs_to :references
|
321
428
|
|
322
|
-
def new_column_definition(name, type, options) # :nodoc:
|
323
|
-
|
324
|
-
|
325
|
-
limit = options.fetch(:limit) do
|
326
|
-
native[type][:limit] if native[type].is_a?(Hash)
|
429
|
+
def new_column_definition(name, type, **options) # :nodoc:
|
430
|
+
if integer_like_primary_key?(type, options)
|
431
|
+
type = integer_like_primary_key_type(type, options)
|
327
432
|
end
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
column.default = options[:default]
|
333
|
-
column.null = options[:null]
|
334
|
-
column.first = options[:first]
|
335
|
-
column.after = options[:after]
|
336
|
-
column.primary_key = type == :primary_key || options[:primary_key]
|
337
|
-
column
|
433
|
+
type = aliased_types(type.to_s, type)
|
434
|
+
options[:primary_key] ||= type == :primary_key
|
435
|
+
options[:null] = false if options[:primary_key]
|
436
|
+
create_column_definition(name, type, options)
|
338
437
|
end
|
339
438
|
|
340
439
|
private
|
341
|
-
|
342
|
-
|
343
|
-
|
440
|
+
def create_column_definition(name, type, options)
|
441
|
+
ColumnDefinition.new(name, type, options)
|
442
|
+
end
|
344
443
|
|
345
|
-
|
346
|
-
|
347
|
-
|
444
|
+
def aliased_types(name, fallback)
|
445
|
+
"timestamp" == name ? :datetime : fallback
|
446
|
+
end
|
348
447
|
|
349
|
-
|
350
|
-
|
351
|
-
|
448
|
+
def integer_like_primary_key?(type, options)
|
449
|
+
options[:primary_key] && [:integer, :bigint].include?(type) && !options.key?(:default)
|
450
|
+
end
|
451
|
+
|
452
|
+
def integer_like_primary_key_type(type, options)
|
453
|
+
type
|
454
|
+
end
|
352
455
|
end
|
353
456
|
|
354
457
|
class AlterTable # :nodoc:
|
@@ -376,16 +479,17 @@ module ActiveRecord
|
|
376
479
|
def add_column(name, type, options)
|
377
480
|
name = name.to_s
|
378
481
|
type = type.to_sym
|
379
|
-
@adds << @td.new_column_definition(name, type, options)
|
482
|
+
@adds << AddColumnDefinition.new(@td.new_column_definition(name, type, options))
|
380
483
|
end
|
381
484
|
end
|
382
485
|
|
383
486
|
# Represents an SQL table in an abstract way for updating a table.
|
384
|
-
# Also see TableDefinition and SchemaStatements#create_table
|
487
|
+
# Also see TableDefinition and {connection.create_table}[rdoc-ref:SchemaStatements#create_table]
|
385
488
|
#
|
386
489
|
# Available transformations are:
|
387
490
|
#
|
388
491
|
# change_table :table do |t|
|
492
|
+
# t.primary_key
|
389
493
|
# t.column
|
390
494
|
# t.index
|
391
495
|
# t.rename_index
|
@@ -398,15 +502,21 @@ module ActiveRecord
|
|
398
502
|
# t.string
|
399
503
|
# t.text
|
400
504
|
# t.integer
|
505
|
+
# t.bigint
|
401
506
|
# t.float
|
402
507
|
# t.decimal
|
508
|
+
# t.numeric
|
403
509
|
# t.datetime
|
404
510
|
# t.timestamp
|
405
511
|
# t.time
|
406
512
|
# t.date
|
407
513
|
# t.binary
|
408
514
|
# t.boolean
|
515
|
+
# t.foreign_key
|
516
|
+
# t.json
|
517
|
+
# t.virtual
|
409
518
|
# t.remove
|
519
|
+
# t.remove_foreign_key
|
410
520
|
# t.remove_references
|
411
521
|
# t.remove_belongs_to
|
412
522
|
# t.remove_index
|
@@ -414,6 +524,8 @@ module ActiveRecord
|
|
414
524
|
# end
|
415
525
|
#
|
416
526
|
class Table
|
527
|
+
include ColumnMethods
|
528
|
+
|
417
529
|
attr_reader :name
|
418
530
|
|
419
531
|
def initialize(table_name, base)
|
@@ -422,33 +534,44 @@ module ActiveRecord
|
|
422
534
|
end
|
423
535
|
|
424
536
|
# Adds a new column to the named table.
|
425
|
-
# See TableDefinition#column for details of the options you can use.
|
426
537
|
#
|
427
|
-
# ====== Creating a simple column
|
428
538
|
# t.column(:name, :string)
|
429
|
-
|
539
|
+
#
|
540
|
+
# See TableDefinition#column for details of the options you can use.
|
541
|
+
def column(column_name, type, **options)
|
542
|
+
index_options = options.delete(:index)
|
430
543
|
@base.add_column(name, column_name, type, options)
|
544
|
+
index(column_name, index_options.is_a?(Hash) ? index_options : {}) if index_options
|
431
545
|
end
|
432
546
|
|
433
|
-
# Checks to see if a column exists.
|
547
|
+
# Checks to see if a column exists.
|
548
|
+
#
|
549
|
+
# t.string(:name) unless t.column_exists?(:name, :string)
|
550
|
+
#
|
551
|
+
# See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?]
|
434
552
|
def column_exists?(column_name, type = nil, options = {})
|
435
553
|
@base.column_exists?(name, column_name, type, options)
|
436
554
|
end
|
437
555
|
|
438
556
|
# Adds a new index to the table. +column_name+ can be a single Symbol, or
|
439
|
-
# an Array of Symbols.
|
557
|
+
# an Array of Symbols.
|
440
558
|
#
|
441
|
-
# ====== Creating a simple index
|
442
559
|
# t.index(:name)
|
443
|
-
# ====== Creating a unique index
|
444
560
|
# t.index([:branch_id, :party_id], unique: true)
|
445
|
-
# ====== Creating a named index
|
446
561
|
# t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
|
562
|
+
#
|
563
|
+
# See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
|
447
564
|
def index(column_name, options = {})
|
448
565
|
@base.add_index(name, column_name, options)
|
449
566
|
end
|
450
567
|
|
451
|
-
# Checks to see if an index exists.
|
568
|
+
# Checks to see if an index exists.
|
569
|
+
#
|
570
|
+
# unless t.index_exists?(:branch_id)
|
571
|
+
# t.index(:branch_id)
|
572
|
+
# end
|
573
|
+
#
|
574
|
+
# See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
|
452
575
|
def index_exists?(column_name, options = {})
|
453
576
|
@base.index_exists?(name, column_name, options)
|
454
577
|
end
|
@@ -456,52 +579,59 @@ module ActiveRecord
|
|
456
579
|
# Renames the given index on the table.
|
457
580
|
#
|
458
581
|
# t.rename_index(:user_id, :account_id)
|
582
|
+
#
|
583
|
+
# See {connection.rename_index}[rdoc-ref:SchemaStatements#rename_index]
|
459
584
|
def rename_index(index_name, new_index_name)
|
460
585
|
@base.rename_index(name, index_name, new_index_name)
|
461
586
|
end
|
462
587
|
|
463
|
-
# Adds timestamps (+created_at+ and +updated_at+) columns to the table.
|
588
|
+
# Adds timestamps (+created_at+ and +updated_at+) columns to the table.
|
589
|
+
#
|
590
|
+
# t.timestamps(null: false)
|
464
591
|
#
|
465
|
-
#
|
592
|
+
# See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
466
593
|
def timestamps(options = {})
|
467
594
|
@base.add_timestamps(name, options)
|
468
595
|
end
|
469
596
|
|
470
597
|
# Changes the column's definition according to the new options.
|
471
|
-
# See TableDefinition#column for details of the options you can use.
|
472
598
|
#
|
473
599
|
# t.change(:name, :string, limit: 80)
|
474
600
|
# t.change(:description, :text)
|
601
|
+
#
|
602
|
+
# See TableDefinition#column for details of the options you can use.
|
475
603
|
def change(column_name, type, options = {})
|
476
604
|
@base.change_column(name, column_name, type, options)
|
477
605
|
end
|
478
606
|
|
479
|
-
# Sets a new default value for a column.
|
607
|
+
# Sets a new default value for a column.
|
480
608
|
#
|
481
609
|
# t.change_default(:qualification, 'new')
|
482
610
|
# t.change_default(:authorized, 1)
|
483
|
-
|
484
|
-
|
611
|
+
# t.change_default(:status, from: nil, to: "draft")
|
612
|
+
#
|
613
|
+
# See {connection.change_column_default}[rdoc-ref:SchemaStatements#change_column_default]
|
614
|
+
def change_default(column_name, default_or_changes)
|
615
|
+
@base.change_column_default(name, column_name, default_or_changes)
|
485
616
|
end
|
486
617
|
|
487
618
|
# Removes the column(s) from the table definition.
|
488
619
|
#
|
489
620
|
# t.remove(:qualification)
|
490
621
|
# t.remove(:qualification, :experience)
|
622
|
+
#
|
623
|
+
# See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
|
491
624
|
def remove(*column_names)
|
492
625
|
@base.remove_columns(name, *column_names)
|
493
626
|
end
|
494
627
|
|
495
628
|
# Removes the given index from the table.
|
496
629
|
#
|
497
|
-
#
|
498
|
-
# t.remove_index :
|
499
|
-
#
|
500
|
-
#
|
501
|
-
#
|
502
|
-
# t.remove_index column: [:branch_id, :party_id]
|
503
|
-
# ====== Remove the index named by_branch_party in the table_name table
|
504
|
-
# t.remove_index name: :by_branch_party
|
630
|
+
# t.remove_index(:branch_id)
|
631
|
+
# t.remove_index(column: [:branch_id, :party_id])
|
632
|
+
# t.remove_index(name: :by_branch_party)
|
633
|
+
#
|
634
|
+
# See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
|
505
635
|
def remove_index(options = {})
|
506
636
|
@base.remove_index(name, options)
|
507
637
|
end
|
@@ -509,6 +639,8 @@ module ActiveRecord
|
|
509
639
|
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
|
510
640
|
#
|
511
641
|
# t.remove_timestamps
|
642
|
+
#
|
643
|
+
# See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
|
512
644
|
def remove_timestamps(options = {})
|
513
645
|
@base.remove_timestamps(name, options)
|
514
646
|
end
|
@@ -516,21 +648,19 @@ module ActiveRecord
|
|
516
648
|
# Renames a column.
|
517
649
|
#
|
518
650
|
# t.rename(:description, :name)
|
651
|
+
#
|
652
|
+
# See {connection.rename_column}[rdoc-ref:SchemaStatements#rename_column]
|
519
653
|
def rename(column_name, new_column_name)
|
520
654
|
@base.rename_column(name, column_name, new_column_name)
|
521
655
|
end
|
522
656
|
|
523
|
-
# Adds a reference.
|
524
|
-
# <tt>references</tt> and <tt>belongs_to</tt> are acceptable. The reference column will be an +integer+
|
525
|
-
# by default, the <tt>:type</tt> option can be used to specify a different type.
|
657
|
+
# Adds a reference.
|
526
658
|
#
|
527
659
|
# t.references(:user)
|
528
|
-
# t.
|
529
|
-
# t.belongs_to(:supplier, polymorphic: true)
|
660
|
+
# t.belongs_to(:supplier, foreign_key: true)
|
530
661
|
#
|
531
|
-
# See SchemaStatements#add_reference
|
532
|
-
def references(*args)
|
533
|
-
options = args.extract_options!
|
662
|
+
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
|
663
|
+
def references(*args, **options)
|
534
664
|
args.each do |ref_name|
|
535
665
|
@base.add_reference(name, ref_name, options)
|
536
666
|
end
|
@@ -538,37 +668,46 @@ module ActiveRecord
|
|
538
668
|
alias :belongs_to :references
|
539
669
|
|
540
670
|
# Removes a reference. Optionally removes a +type+ column.
|
541
|
-
# <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
|
542
671
|
#
|
543
672
|
# t.remove_references(:user)
|
544
673
|
# t.remove_belongs_to(:supplier, polymorphic: true)
|
545
674
|
#
|
546
|
-
# See SchemaStatements#remove_reference
|
547
|
-
def remove_references(*args)
|
548
|
-
options = args.extract_options!
|
675
|
+
# See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
|
676
|
+
def remove_references(*args, **options)
|
549
677
|
args.each do |ref_name|
|
550
678
|
@base.remove_reference(name, ref_name, options)
|
551
679
|
end
|
552
680
|
end
|
553
681
|
alias :remove_belongs_to :remove_references
|
554
682
|
|
555
|
-
# Adds a
|
683
|
+
# Adds a foreign key to the table using a supplied table name.
|
556
684
|
#
|
557
|
-
# t.
|
558
|
-
# t.
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
@base.add_column(name, column_name, column_type, options)
|
564
|
-
end
|
565
|
-
end
|
685
|
+
# t.foreign_key(:authors)
|
686
|
+
# t.foreign_key(:authors, column: :author_id, primary_key: "id")
|
687
|
+
#
|
688
|
+
# See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
|
689
|
+
def foreign_key(*args)
|
690
|
+
@base.add_foreign_key(name, *args)
|
566
691
|
end
|
567
692
|
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
693
|
+
# Removes the given foreign key from the table.
|
694
|
+
#
|
695
|
+
# t.remove_foreign_key(:authors)
|
696
|
+
# t.remove_foreign_key(column: :author_id)
|
697
|
+
#
|
698
|
+
# See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
|
699
|
+
def remove_foreign_key(*args)
|
700
|
+
@base.remove_foreign_key(name, *args)
|
701
|
+
end
|
702
|
+
|
703
|
+
# Checks to see if a foreign key exists.
|
704
|
+
#
|
705
|
+
# t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
|
706
|
+
#
|
707
|
+
# See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
|
708
|
+
def foreign_key_exists?(*args)
|
709
|
+
@base.foreign_key_exists?(name, *args)
|
710
|
+
end
|
572
711
|
end
|
573
712
|
end
|
574
713
|
end
|