activerecord 4.2.0 → 5.2.8.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

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