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