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