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.

Files changed (251) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1638 -1132
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -8
  5. data/examples/performance.rb +2 -3
  6. data/examples/simple.rb +0 -1
  7. data/lib/active_record.rb +7 -2
  8. data/lib/active_record/aggregations.rb +34 -21
  9. data/lib/active_record/association_relation.rb +7 -4
  10. data/lib/active_record/associations.rb +347 -218
  11. data/lib/active_record/associations/alias_tracker.rb +19 -16
  12. data/lib/active_record/associations/association.rb +22 -10
  13. data/lib/active_record/associations/association_scope.rb +75 -104
  14. data/lib/active_record/associations/belongs_to_association.rb +21 -32
  15. data/lib/active_record/associations/builder/association.rb +28 -34
  16. data/lib/active_record/associations/builder/belongs_to.rb +43 -18
  17. data/lib/active_record/associations/builder/collection_association.rb +7 -19
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +16 -11
  19. data/lib/active_record/associations/builder/has_many.rb +4 -4
  20. data/lib/active_record/associations/builder/has_one.rb +11 -6
  21. data/lib/active_record/associations/builder/singular_association.rb +13 -11
  22. data/lib/active_record/associations/collection_association.rb +85 -69
  23. data/lib/active_record/associations/collection_proxy.rb +104 -46
  24. data/lib/active_record/associations/foreign_association.rb +1 -1
  25. data/lib/active_record/associations/has_many_association.rb +21 -78
  26. data/lib/active_record/associations/has_many_through_association.rb +6 -47
  27. data/lib/active_record/associations/has_one_association.rb +12 -5
  28. data/lib/active_record/associations/join_dependency.rb +38 -22
  29. data/lib/active_record/associations/join_dependency/join_association.rb +15 -14
  30. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  31. data/lib/active_record/associations/preloader.rb +14 -4
  32. data/lib/active_record/associations/preloader/association.rb +52 -71
  33. data/lib/active_record/associations/preloader/collection_association.rb +0 -7
  34. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  35. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  36. data/lib/active_record/associations/preloader/singular_association.rb +0 -1
  37. data/lib/active_record/associations/preloader/through_association.rb +36 -17
  38. data/lib/active_record/associations/singular_association.rb +13 -1
  39. data/lib/active_record/associations/through_association.rb +12 -4
  40. data/lib/active_record/attribute.rb +69 -19
  41. data/lib/active_record/attribute/user_provided_default.rb +28 -0
  42. data/lib/active_record/attribute_assignment.rb +19 -140
  43. data/lib/active_record/attribute_decorators.rb +6 -5
  44. data/lib/active_record/attribute_methods.rb +69 -44
  45. data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
  46. data/lib/active_record/attribute_methods/dirty.rb +46 -86
  47. data/lib/active_record/attribute_methods/primary_key.rb +16 -3
  48. data/lib/active_record/attribute_methods/query.rb +2 -2
  49. data/lib/active_record/attribute_methods/read.rb +31 -59
  50. data/lib/active_record/attribute_methods/serialization.rb +13 -16
  51. data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -14
  52. data/lib/active_record/attribute_methods/write.rb +13 -37
  53. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  54. data/lib/active_record/attribute_set.rb +32 -3
  55. data/lib/active_record/attribute_set/builder.rb +42 -16
  56. data/lib/active_record/attributes.rb +199 -81
  57. data/lib/active_record/autosave_association.rb +54 -17
  58. data/lib/active_record/base.rb +32 -23
  59. data/lib/active_record/callbacks.rb +39 -43
  60. data/lib/active_record/coders/json.rb +1 -1
  61. data/lib/active_record/coders/yaml_column.rb +20 -8
  62. data/lib/active_record/collection_cache_key.rb +50 -0
  63. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +467 -189
  64. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
  65. data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -62
  66. data/lib/active_record/connection_adapters/abstract/query_cache.rb +39 -4
  67. data/lib/active_record/connection_adapters/abstract/quoting.rb +86 -13
  68. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  69. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
  70. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -188
  71. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
  72. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +407 -156
  73. data/lib/active_record/connection_adapters/abstract/transaction.rb +51 -34
  74. data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -71
  75. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +433 -399
  76. data/lib/active_record/connection_adapters/column.rb +28 -43
  77. data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
  78. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  79. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  80. data/lib/active_record/connection_adapters/mysql/database_statements.rb +108 -0
  81. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  82. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  83. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
  84. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
  85. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
  86. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  87. data/lib/active_record/connection_adapters/mysql2_adapter.rb +25 -166
  88. data/lib/active_record/connection_adapters/postgresql/column.rb +33 -11
  89. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -72
  90. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
  92. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +37 -57
  93. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +3 -3
  94. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -2
  95. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
  97. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +13 -3
  98. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
  99. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
  102. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +56 -19
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +250 -154
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -2
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +264 -170
  116. data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  118. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  121. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +151 -194
  122. data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
  123. data/lib/active_record/connection_handling.rb +37 -14
  124. data/lib/active_record/core.rb +92 -108
  125. data/lib/active_record/counter_cache.rb +13 -24
  126. data/lib/active_record/dynamic_matchers.rb +1 -20
  127. data/lib/active_record/enum.rb +116 -76
  128. data/lib/active_record/errors.rb +87 -48
  129. data/lib/active_record/explain.rb +20 -9
  130. data/lib/active_record/explain_registry.rb +1 -1
  131. data/lib/active_record/explain_subscriber.rb +1 -1
  132. data/lib/active_record/fixture_set/file.rb +26 -5
  133. data/lib/active_record/fixtures.rb +77 -41
  134. data/lib/active_record/gem_version.rb +4 -4
  135. data/lib/active_record/inheritance.rb +32 -40
  136. data/lib/active_record/integration.rb +17 -14
  137. data/lib/active_record/internal_metadata.rb +56 -0
  138. data/lib/active_record/legacy_yaml_adapter.rb +18 -2
  139. data/lib/active_record/locale/en.yml +3 -2
  140. data/lib/active_record/locking/optimistic.rb +15 -15
  141. data/lib/active_record/locking/pessimistic.rb +1 -1
  142. data/lib/active_record/log_subscriber.rb +48 -24
  143. data/lib/active_record/migration.rb +362 -111
  144. data/lib/active_record/migration/command_recorder.rb +59 -18
  145. data/lib/active_record/migration/compatibility.rb +126 -0
  146. data/lib/active_record/model_schema.rb +270 -73
  147. data/lib/active_record/nested_attributes.rb +58 -29
  148. data/lib/active_record/no_touching.rb +4 -0
  149. data/lib/active_record/null_relation.rb +16 -8
  150. data/lib/active_record/persistence.rb +152 -90
  151. data/lib/active_record/query_cache.rb +18 -23
  152. data/lib/active_record/querying.rb +12 -11
  153. data/lib/active_record/railtie.rb +23 -16
  154. data/lib/active_record/railties/controller_runtime.rb +1 -1
  155. data/lib/active_record/railties/databases.rake +52 -41
  156. data/lib/active_record/readonly_attributes.rb +1 -1
  157. data/lib/active_record/reflection.rb +302 -115
  158. data/lib/active_record/relation.rb +187 -120
  159. data/lib/active_record/relation/batches.rb +141 -36
  160. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  161. data/lib/active_record/relation/calculations.rb +92 -117
  162. data/lib/active_record/relation/delegation.rb +8 -20
  163. data/lib/active_record/relation/finder_methods.rb +173 -89
  164. data/lib/active_record/relation/from_clause.rb +32 -0
  165. data/lib/active_record/relation/merger.rb +16 -42
  166. data/lib/active_record/relation/predicate_builder.rb +120 -107
  167. data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
  168. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
  169. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  170. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  171. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  172. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  173. data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
  174. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  175. data/lib/active_record/relation/query_attribute.rb +19 -0
  176. data/lib/active_record/relation/query_methods.rb +308 -244
  177. data/lib/active_record/relation/record_fetch_warning.rb +49 -0
  178. data/lib/active_record/relation/spawn_methods.rb +4 -7
  179. data/lib/active_record/relation/where_clause.rb +174 -0
  180. data/lib/active_record/relation/where_clause_factory.rb +38 -0
  181. data/lib/active_record/result.rb +11 -4
  182. data/lib/active_record/runtime_registry.rb +1 -1
  183. data/lib/active_record/sanitization.rb +105 -66
  184. data/lib/active_record/schema.rb +26 -22
  185. data/lib/active_record/schema_dumper.rb +54 -37
  186. data/lib/active_record/schema_migration.rb +11 -14
  187. data/lib/active_record/scoping.rb +34 -16
  188. data/lib/active_record/scoping/default.rb +28 -10
  189. data/lib/active_record/scoping/named.rb +59 -26
  190. data/lib/active_record/secure_token.rb +38 -0
  191. data/lib/active_record/serialization.rb +3 -5
  192. data/lib/active_record/statement_cache.rb +17 -15
  193. data/lib/active_record/store.rb +8 -3
  194. data/lib/active_record/suppressor.rb +58 -0
  195. data/lib/active_record/table_metadata.rb +69 -0
  196. data/lib/active_record/tasks/database_tasks.rb +66 -49
  197. data/lib/active_record/tasks/mysql_database_tasks.rb +6 -14
  198. data/lib/active_record/tasks/postgresql_database_tasks.rb +12 -3
  199. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  200. data/lib/active_record/timestamp.rb +20 -9
  201. data/lib/active_record/touch_later.rb +63 -0
  202. data/lib/active_record/transactions.rb +139 -57
  203. data/lib/active_record/type.rb +66 -17
  204. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  205. data/lib/active_record/type/date.rb +2 -45
  206. data/lib/active_record/type/date_time.rb +2 -49
  207. data/lib/active_record/type/internal/abstract_json.rb +33 -0
  208. data/lib/active_record/type/internal/timezone.rb +15 -0
  209. data/lib/active_record/type/serialized.rb +15 -14
  210. data/lib/active_record/type/time.rb +10 -16
  211. data/lib/active_record/type/type_map.rb +4 -4
  212. data/lib/active_record/type_caster.rb +7 -0
  213. data/lib/active_record/type_caster/connection.rb +29 -0
  214. data/lib/active_record/type_caster/map.rb +19 -0
  215. data/lib/active_record/validations.rb +33 -32
  216. data/lib/active_record/validations/absence.rb +23 -0
  217. data/lib/active_record/validations/associated.rb +10 -3
  218. data/lib/active_record/validations/length.rb +24 -0
  219. data/lib/active_record/validations/presence.rb +11 -12
  220. data/lib/active_record/validations/uniqueness.rb +33 -33
  221. data/lib/rails/generators/active_record/migration.rb +15 -0
  222. data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -5
  223. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
  224. data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -1
  225. data/lib/rails/generators/active_record/model/model_generator.rb +33 -16
  226. data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
  227. data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
  228. metadata +58 -34
  229. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  230. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  231. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
  232. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  233. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  234. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  235. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  236. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  237. data/lib/active_record/type/big_integer.rb +0 -13
  238. data/lib/active_record/type/binary.rb +0 -50
  239. data/lib/active_record/type/boolean.rb +0 -31
  240. data/lib/active_record/type/decimal.rb +0 -64
  241. data/lib/active_record/type/decimal_without_scale.rb +0 -11
  242. data/lib/active_record/type/decorator.rb +0 -14
  243. data/lib/active_record/type/float.rb +0 -19
  244. data/lib/active_record/type/integer.rb +0 -59
  245. data/lib/active_record/type/mutable.rb +0 -16
  246. data/lib/active_record/type/numeric.rb +0 -36
  247. data/lib/active_record/type/string.rb +0 -40
  248. data/lib/active_record/type/text.rb +0 -11
  249. data/lib/active_record/type/time_value.rb +0 -38
  250. data/lib/active_record/type/unsigned_integer.rb +0 -15
  251. data/lib/active_record/type/value.rb +0 -110
@@ -1,8 +1,8 @@
1
1
  module ActiveRecord
2
2
  module ConnectionAdapters
3
- module Savepoints #:nodoc:
4
- def supports_savepoints?
5
- true
3
+ module Savepoints
4
+ def current_savepoint_name
5
+ current_transaction.savepoint_name
6
6
  end
7
7
 
8
8
  def create_savepoint(name = current_savepoint_name)
@@ -14,38 +14,58 @@ module ActiveRecord
14
14
  send m, o
15
15
  end
16
16
 
17
- def visit_AddColumn(o)
18
- "ADD #{accept(o)}"
19
- end
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| visit_AddColumn col }.join(' ')
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 = type_to_sql(o.type, o.limit, o.precision, o.scale)
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
- create_sql << "#{quote_table_name(o.name)} "
40
- create_sql << "(#{o.columns.map { |c| accept c }.join(', ')}) " unless o.as
41
- create_sql << "#{o.options}"
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 visit_AddForeignKey(o)
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
- ADD CONSTRAINT #{quote_column_name(o.name)}
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 #{quote_value(options[:default], options[:column])}" if options_include_default?(options)
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 quote_value(value, column)
96
- column.sql_type ||= type_to_sql(column.type, column.limit, column.precision, column.scale)
97
- column.cast_type ||= type_for_column(column)
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, :cast_type) #:nodoc:
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 ChangeColumnDefinition < Struct.new(:column, :type, :options) #:nodoc:
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
- module TimestampDefaultDeprecation # :nodoc:
60
- def emit_warning_if_null_unspecified(sym, options)
61
- return if options.key?(:null)
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
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
64
- `##{sym}` 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
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 +create_table+
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 TimestampDefaultDeprecation
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(types, name, temporary, options, as = nil)
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
- @native = types
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 columns; @columns_hash.values; end
111
-
112
- # Appends a primary key definition to the table definition.
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
- # The +type+ parameter is normally one of the migrations native types,
125
- # which is one of the following:
126
- # <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
127
- # <tt>:integer</tt>, <tt>:float</tt>, <tt>:decimal</tt>,
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.column(:bill_gates_money, :decimal, precision: 15, scale: 2)
191
- # # => bill_gates_money DECIMAL(15,2)
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 +column+ directly, you can also work with the short-hand definitions for the default types.
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 <tt>add_index</tt>. So what can be written like this:
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] = options
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
- emit_warning_if_null_unspecified(:timestamps, options)
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
- column("#{col}_id", type, options)
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. See SchemaStatements#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. See SchemaStatements#add_index
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. See SchemaStatements#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. See SchemaStatements#add_timestamps
516
+ # Adds timestamps (+created_at+ and +updated_at+) columns to the table.
477
517
  #
478
- # t.timestamps null: false
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. See SchemaStatements#change_column_default
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
- def change_default(column_name, default)
497
- @base.change_column_default(name, column_name, default)
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
- # ====== Remove the index_table_name_on_column in the table_name table
511
- # t.remove_index :column
512
- # ====== Remove the index named index_table_name_on_branch_id in the table_name table
513
- # t.remove_index column: :branch_id
514
- # ====== Remove the index named index_table_name_on_branch_id_and_party_id in the table_name table
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 column or columns of a specified type
613
+ # Adds a foreign key.
566
614
  #
567
- # t.string(:goat)
568
- # t.string(:goat, :sheep)
569
- [:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
570
- define_method column_type do |*args|
571
- options = args.extract_options!
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
- private
579
- def native
580
- @base.native_database_types
581
- end
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