activerecord 6.0.6.1 → 6.1.0.rc1

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 (242) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +764 -942
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/association_relation.rb +22 -14
  7. data/lib/active_record/associations/alias_tracker.rb +19 -15
  8. data/lib/active_record/associations/association.rb +39 -27
  9. data/lib/active_record/associations/association_scope.rb +11 -15
  10. data/lib/active_record/associations/belongs_to_association.rb +15 -5
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  12. data/lib/active_record/associations/builder/association.rb +9 -3
  13. data/lib/active_record/associations/builder/belongs_to.rb +10 -7
  14. data/lib/active_record/associations/builder/collection_association.rb +5 -4
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
  16. data/lib/active_record/associations/builder/has_many.rb +6 -2
  17. data/lib/active_record/associations/builder/has_one.rb +11 -14
  18. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  19. data/lib/active_record/associations/collection_association.rb +19 -13
  20. data/lib/active_record/associations/collection_proxy.rb +12 -5
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -2
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -4
  24. data/lib/active_record/associations/has_one_association.rb +15 -1
  25. data/lib/active_record/associations/join_dependency/join_association.rb +29 -14
  26. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +63 -49
  28. data/lib/active_record/associations/preloader/association.rb +13 -5
  29. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  30. data/lib/active_record/associations/preloader.rb +5 -3
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations.rb +114 -11
  33. data/lib/active_record/attribute_assignment.rb +10 -8
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  35. data/lib/active_record/attribute_methods/dirty.rb +1 -11
  36. data/lib/active_record/attribute_methods/primary_key.rb +6 -2
  37. data/lib/active_record/attribute_methods/query.rb +3 -6
  38. data/lib/active_record/attribute_methods/read.rb +8 -11
  39. data/lib/active_record/attribute_methods/serialization.rb +4 -4
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
  41. data/lib/active_record/attribute_methods/write.rb +12 -20
  42. data/lib/active_record/attribute_methods.rb +52 -48
  43. data/lib/active_record/attributes.rb +27 -7
  44. data/lib/active_record/autosave_association.rb +47 -30
  45. data/lib/active_record/base.rb +2 -14
  46. data/lib/active_record/callbacks.rb +32 -22
  47. data/lib/active_record/coders/yaml_column.rb +2 -24
  48. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +180 -134
  49. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  50. data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -22
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -7
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +35 -44
  53. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +110 -30
  56. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +224 -85
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -24
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +31 -70
  60. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
  61. data/lib/active_record/connection_adapters/column.rb +15 -1
  62. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  63. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -24
  65. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +33 -6
  68. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  69. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  70. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -3
  71. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
  73. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  74. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  75. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +12 -53
  77. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  78. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  79. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -10
  80. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  81. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  84. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  88. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
  90. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
  91. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  92. data/lib/active_record/connection_adapters/postgresql_adapter.rb +72 -55
  93. data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
  94. data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
  95. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +30 -5
  96. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
  97. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  98. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
  99. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
  100. data/lib/active_record/connection_adapters.rb +50 -0
  101. data/lib/active_record/connection_handling.rb +210 -71
  102. data/lib/active_record/core.rb +214 -58
  103. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  104. data/lib/active_record/database_configurations/database_config.rb +52 -9
  105. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  106. data/lib/active_record/database_configurations/url_config.rb +15 -40
  107. data/lib/active_record/database_configurations.rb +124 -85
  108. data/lib/active_record/delegated_type.rb +209 -0
  109. data/lib/active_record/destroy_association_async_job.rb +36 -0
  110. data/lib/active_record/enum.rb +33 -23
  111. data/lib/active_record/errors.rb +47 -12
  112. data/lib/active_record/explain.rb +9 -4
  113. data/lib/active_record/explain_subscriber.rb +1 -1
  114. data/lib/active_record/fixture_set/file.rb +10 -17
  115. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  116. data/lib/active_record/fixture_set/render_context.rb +1 -1
  117. data/lib/active_record/fixture_set/table_row.rb +2 -2
  118. data/lib/active_record/fixtures.rb +54 -8
  119. data/lib/active_record/gem_version.rb +3 -3
  120. data/lib/active_record/inheritance.rb +40 -18
  121. data/lib/active_record/insert_all.rb +32 -5
  122. data/lib/active_record/integration.rb +3 -5
  123. data/lib/active_record/internal_metadata.rb +15 -4
  124. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  125. data/lib/active_record/locking/optimistic.rb +13 -16
  126. data/lib/active_record/locking/pessimistic.rb +6 -2
  127. data/lib/active_record/log_subscriber.rb +26 -8
  128. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  129. data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
  130. data/lib/active_record/middleware/database_selector.rb +4 -1
  131. data/lib/active_record/migration/command_recorder.rb +47 -27
  132. data/lib/active_record/migration/compatibility.rb +67 -17
  133. data/lib/active_record/migration.rb +113 -83
  134. data/lib/active_record/model_schema.rb +88 -42
  135. data/lib/active_record/nested_attributes.rb +2 -3
  136. data/lib/active_record/no_touching.rb +1 -1
  137. data/lib/active_record/persistence.rb +50 -45
  138. data/lib/active_record/query_cache.rb +15 -5
  139. data/lib/active_record/querying.rb +11 -6
  140. data/lib/active_record/railtie.rb +64 -44
  141. data/lib/active_record/railties/databases.rake +253 -98
  142. data/lib/active_record/readonly_attributes.rb +4 -0
  143. data/lib/active_record/reflection.rb +59 -44
  144. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  145. data/lib/active_record/relation/batches.rb +38 -31
  146. data/lib/active_record/relation/calculations.rb +100 -43
  147. data/lib/active_record/relation/finder_methods.rb +44 -14
  148. data/lib/active_record/relation/from_clause.rb +1 -1
  149. data/lib/active_record/relation/merger.rb +20 -23
  150. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  151. data/lib/active_record/relation/predicate_builder/association_query_value.rb +2 -2
  152. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
  153. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  154. data/lib/active_record/relation/predicate_builder.rb +57 -33
  155. data/lib/active_record/relation/query_methods.rb +319 -198
  156. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  157. data/lib/active_record/relation/spawn_methods.rb +6 -5
  158. data/lib/active_record/relation/where_clause.rb +104 -57
  159. data/lib/active_record/relation.rb +90 -64
  160. data/lib/active_record/result.rb +41 -33
  161. data/lib/active_record/runtime_registry.rb +2 -2
  162. data/lib/active_record/sanitization.rb +6 -17
  163. data/lib/active_record/schema_dumper.rb +34 -4
  164. data/lib/active_record/schema_migration.rb +0 -4
  165. data/lib/active_record/scoping/named.rb +1 -17
  166. data/lib/active_record/secure_token.rb +16 -8
  167. data/lib/active_record/serialization.rb +5 -3
  168. data/lib/active_record/signed_id.rb +116 -0
  169. data/lib/active_record/statement_cache.rb +20 -4
  170. data/lib/active_record/store.rb +2 -2
  171. data/lib/active_record/suppressor.rb +2 -2
  172. data/lib/active_record/table_metadata.rb +36 -52
  173. data/lib/active_record/tasks/database_tasks.rb +139 -113
  174. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
  175. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
  176. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
  177. data/lib/active_record/test_databases.rb +5 -4
  178. data/lib/active_record/test_fixtures.rb +36 -33
  179. data/lib/active_record/timestamp.rb +4 -6
  180. data/lib/active_record/touch_later.rb +21 -21
  181. data/lib/active_record/transactions.rb +15 -64
  182. data/lib/active_record/type/serialized.rb +6 -2
  183. data/lib/active_record/type.rb +8 -1
  184. data/lib/active_record/type_caster/connection.rb +0 -1
  185. data/lib/active_record/type_caster/map.rb +8 -5
  186. data/lib/active_record/validations/associated.rb +1 -1
  187. data/lib/active_record/validations/numericality.rb +35 -0
  188. data/lib/active_record/validations/uniqueness.rb +24 -4
  189. data/lib/active_record/validations.rb +1 -0
  190. data/lib/active_record.rb +7 -14
  191. data/lib/arel/attributes/attribute.rb +4 -0
  192. data/lib/arel/collectors/bind.rb +5 -0
  193. data/lib/arel/collectors/composite.rb +8 -0
  194. data/lib/arel/collectors/sql_string.rb +7 -0
  195. data/lib/arel/collectors/substitute_binds.rb +7 -0
  196. data/lib/arel/nodes/binary.rb +82 -8
  197. data/lib/arel/nodes/bind_param.rb +8 -0
  198. data/lib/arel/nodes/casted.rb +21 -9
  199. data/lib/arel/nodes/equality.rb +6 -9
  200. data/lib/arel/nodes/grouping.rb +3 -0
  201. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  202. data/lib/arel/nodes/in.rb +8 -1
  203. data/lib/arel/nodes/infix_operation.rb +13 -1
  204. data/lib/arel/nodes/join_source.rb +1 -1
  205. data/lib/arel/nodes/node.rb +7 -6
  206. data/lib/arel/nodes/ordering.rb +27 -0
  207. data/lib/arel/nodes/sql_literal.rb +3 -0
  208. data/lib/arel/nodes/table_alias.rb +7 -3
  209. data/lib/arel/nodes/unary.rb +0 -1
  210. data/lib/arel/nodes.rb +3 -1
  211. data/lib/arel/predications.rb +12 -18
  212. data/lib/arel/select_manager.rb +1 -2
  213. data/lib/arel/table.rb +13 -5
  214. data/lib/arel/visitors/dot.rb +14 -2
  215. data/lib/arel/visitors/mysql.rb +11 -1
  216. data/lib/arel/visitors/postgresql.rb +15 -4
  217. data/lib/arel/visitors/to_sql.rb +89 -78
  218. data/lib/arel/visitors.rb +0 -7
  219. data/lib/arel.rb +5 -13
  220. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  221. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  222. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
  223. data/lib/rails/generators/active_record/migration.rb +6 -1
  224. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  225. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  226. metadata +30 -32
  227. data/lib/active_record/advisory_lock_base.rb +0 -18
  228. data/lib/active_record/attribute_decorators.rb +0 -88
  229. data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
  230. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  231. data/lib/active_record/define_callbacks.rb +0 -22
  232. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  233. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  234. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  235. data/lib/arel/attributes.rb +0 -22
  236. data/lib/arel/visitors/depth_first.rb +0 -203
  237. data/lib/arel/visitors/ibm_db.rb +0 -34
  238. data/lib/arel/visitors/informix.rb +0 -62
  239. data/lib/arel/visitors/mssql.rb +0 -156
  240. data/lib/arel/visitors/oracle.rb +0 -158
  241. data/lib/arel/visitors/oracle12.rb +0 -65
  242. data/lib/arel/visitors/where_sql.rb +0 -22
@@ -82,12 +82,9 @@ module Arel # :nodoc: all
82
82
  end
83
83
 
84
84
  def visit_Arel_Nodes_Casted(o, collector)
85
- collector << quoted(o.val, o.attribute).to_s
86
- end
87
-
88
- def visit_Arel_Nodes_Quoted(o, collector)
89
- collector << quoted(o.expr, nil).to_s
85
+ collector << quote(o.value_for_database).to_s
90
86
  end
87
+ alias :visit_Arel_Nodes_Quoted :visit_Arel_Nodes_Casted
91
88
 
92
89
  def visit_Arel_Nodes_True(o, collector)
93
90
  collector << "TRUE"
@@ -195,12 +192,12 @@ module Arel # :nodoc: all
195
192
 
196
193
  def visit_Arel_Nodes_With(o, collector)
197
194
  collector << "WITH "
198
- inject_join o.children, collector, ", "
195
+ collect_ctes(o.children, collector)
199
196
  end
200
197
 
201
198
  def visit_Arel_Nodes_WithRecursive(o, collector)
202
199
  collector << "WITH RECURSIVE "
203
- inject_join o.children, collector, ", "
200
+ collect_ctes(o.children, collector)
204
201
  end
205
202
 
206
203
  def visit_Arel_Nodes_Union(o, collector)
@@ -324,6 +321,29 @@ module Arel # :nodoc: all
324
321
  end
325
322
  end
326
323
 
324
+ def visit_Arel_Nodes_HomogeneousIn(o, collector)
325
+ collector.preparable = false
326
+
327
+ collector << quote_table_name(o.table_name) << "." << quote_column_name(o.column_name)
328
+
329
+ if o.type == :in
330
+ collector << " IN ("
331
+ else
332
+ collector << " NOT IN ("
333
+ end
334
+
335
+ values = o.casted_values
336
+
337
+ if values.empty?
338
+ collector << @connection.quote(nil)
339
+ else
340
+ collector.add_binds(values, &bind_block)
341
+ end
342
+
343
+ collector << ")"
344
+ collector
345
+ end
346
+
327
347
  def visit_Arel_SelectManager(o, collector)
328
348
  collector << "("
329
349
  visit(o.ast, collector) << ")"
@@ -513,64 +533,35 @@ module Arel # :nodoc: all
513
533
  end
514
534
 
515
535
  def visit_Arel_Nodes_In(o, collector)
516
- unless Array === o.right
517
- return collect_in_clause(o.left, o.right, collector)
518
- end
519
-
520
- unless o.right.empty?
521
- o.right.delete_if { |value| unboundable?(value) }
522
- end
536
+ collector.preparable = false
537
+ attr, values = o.left, o.right
523
538
 
524
- return collector << "1=0" if o.right.empty?
525
-
526
- in_clause_length = @connection.in_clause_length
527
-
528
- if !in_clause_length || o.right.length <= in_clause_length
529
- collect_in_clause(o.left, o.right, collector)
530
- else
531
- collector << "("
532
- o.right.each_slice(in_clause_length).each_with_index do |right, i|
533
- collector << " OR " unless i == 0
534
- collect_in_clause(o.left, right, collector)
539
+ if Array === values
540
+ unless values.empty?
541
+ values.delete_if { |value| unboundable?(value) }
535
542
  end
536
- collector << ")"
543
+
544
+ return collector << "1=0" if values.empty?
537
545
  end
538
- end
539
546
 
540
- def collect_in_clause(left, right, collector)
541
- collector = visit left, collector
542
- collector << " IN ("
543
- visit(right, collector) << ")"
547
+ visit(attr, collector) << " IN ("
548
+ visit(values, collector) << ")"
544
549
  end
545
550
 
546
551
  def visit_Arel_Nodes_NotIn(o, collector)
547
- unless Array === o.right
548
- return collect_not_in_clause(o.left, o.right, collector)
549
- end
550
-
551
- unless o.right.empty?
552
- o.right.delete_if { |value| unboundable?(value) }
553
- end
552
+ collector.preparable = false
553
+ attr, values = o.left, o.right
554
554
 
555
- return collector << "1=1" if o.right.empty?
556
-
557
- in_clause_length = @connection.in_clause_length
558
-
559
- if !in_clause_length || o.right.length <= in_clause_length
560
- collect_not_in_clause(o.left, o.right, collector)
561
- else
562
- o.right.each_slice(in_clause_length).each_with_index do |right, i|
563
- collector << " AND " unless i == 0
564
- collect_not_in_clause(o.left, right, collector)
555
+ if Array === values
556
+ unless values.empty?
557
+ values.delete_if { |value| unboundable?(value) }
565
558
  end
566
- collector
559
+
560
+ return collector << "1=1" if values.empty?
567
561
  end
568
- end
569
562
 
570
- def collect_not_in_clause(left, right, collector)
571
- collector = visit left, collector
572
- collector << " NOT IN ("
573
- visit(right, collector) << ")"
563
+ visit(attr, collector) << " NOT IN ("
564
+ visit(values, collector) << ")"
574
565
  end
575
566
 
576
567
  def visit_Arel_Nodes_And(o, collector)
@@ -578,9 +569,18 @@ module Arel # :nodoc: all
578
569
  end
579
570
 
580
571
  def visit_Arel_Nodes_Or(o, collector)
581
- collector = visit o.left, collector
582
- collector << " OR "
583
- visit o.right, collector
572
+ stack = [o.right, o.left]
573
+
574
+ while o = stack.pop
575
+ if o.is_a?(Arel::Nodes::Or)
576
+ stack.push o.right, o.left
577
+ else
578
+ visit o, collector
579
+ collector << " OR " unless stack.empty?
580
+ end
581
+ end
582
+
583
+ collector
584
584
  end
585
585
 
586
586
  def visit_Arel_Nodes_Assignment(o, collector)
@@ -689,28 +689,23 @@ module Arel # :nodoc: all
689
689
  join_name = o.relation.table_alias || o.relation.name
690
690
  collector << quote_table_name(join_name) << "." << quote_column_name(o.name)
691
691
  end
692
- alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
693
- alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
694
- alias :visit_Arel_Attributes_Decimal :visit_Arel_Attributes_Attribute
695
- alias :visit_Arel_Attributes_String :visit_Arel_Attributes_Attribute
696
- alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute
697
- alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute
698
692
 
699
- def literal(o, collector); collector << o.to_s; end
693
+ BIND_BLOCK = proc { "?" }
694
+ private_constant :BIND_BLOCK
695
+
696
+ def bind_block; BIND_BLOCK; end
700
697
 
701
698
  def visit_Arel_Nodes_BindParam(o, collector)
702
- collector.add_bind(o.value) { "?" }
699
+ collector.add_bind(o.value, &bind_block)
703
700
  end
704
701
 
705
- alias :visit_Arel_Nodes_SqlLiteral :literal
706
- alias :visit_Integer :literal
702
+ def visit_Arel_Nodes_SqlLiteral(o, collector)
703
+ collector.preparable = false
704
+ collector << o.to_s
705
+ end
707
706
 
708
- def quoted(o, a)
709
- if a && a.able_to_type_cast?
710
- quote(a.type_cast_for_database(o))
711
- else
712
- quote(o)
713
- end
707
+ def visit_Integer(o, collector)
708
+ collector << o.to_s
714
709
  end
715
710
 
716
711
  def unsupported(o, collector)
@@ -738,11 +733,6 @@ module Arel # :nodoc: all
738
733
  visit o.right, collector
739
734
  end
740
735
 
741
- alias :visit_Arel_Nodes_Addition :visit_Arel_Nodes_InfixOperation
742
- alias :visit_Arel_Nodes_Subtraction :visit_Arel_Nodes_InfixOperation
743
- alias :visit_Arel_Nodes_Multiplication :visit_Arel_Nodes_InfixOperation
744
- alias :visit_Arel_Nodes_Division :visit_Arel_Nodes_InfixOperation
745
-
746
736
  def visit_Arel_Nodes_UnaryOperation(o, collector)
747
737
  collector << " #{o.operator} "
748
738
  visit o.expr, collector
@@ -883,6 +873,27 @@ module Arel # :nodoc: all
883
873
  collector << " IS NULL)"
884
874
  collector << " THEN 0 ELSE 1 END"
885
875
  end
876
+
877
+ def collect_ctes(children, collector)
878
+ children.each_with_index do |child, i|
879
+ collector << ", " unless i == 0
880
+
881
+ case child
882
+ when Arel::Nodes::As
883
+ name = child.left.name
884
+ relation = child.right
885
+ when Arel::Nodes::TableAlias
886
+ name = child.name
887
+ relation = child.relation
888
+ end
889
+
890
+ collector << quote_table_name(name)
891
+ collector << " AS "
892
+ visit relation, collector
893
+ end
894
+
895
+ collector
896
+ end
886
897
  end
887
898
  end
888
899
  end
data/lib/arel/visitors.rb CHANGED
@@ -1,18 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "arel/visitors/visitor"
4
- require "arel/visitors/depth_first"
5
4
  require "arel/visitors/to_sql"
6
5
  require "arel/visitors/sqlite"
7
6
  require "arel/visitors/postgresql"
8
7
  require "arel/visitors/mysql"
9
- require "arel/visitors/mssql"
10
- require "arel/visitors/oracle"
11
- require "arel/visitors/oracle12"
12
- require "arel/visitors/where_sql"
13
8
  require "arel/visitors/dot"
14
- require "arel/visitors/ibm_db"
15
- require "arel/visitors/informix"
16
9
 
17
10
  module Arel # :nodoc: all
18
11
  module Visitors
data/lib/arel.rb CHANGED
@@ -12,7 +12,7 @@ require "arel/math"
12
12
  require "arel/alias_predication"
13
13
  require "arel/order_predications"
14
14
  require "arel/table"
15
- require "arel/attributes"
15
+ require "arel/attributes/attribute"
16
16
 
17
17
  require "arel/visitors"
18
18
  require "arel/collectors/sql_string"
@@ -43,20 +43,12 @@ module Arel
43
43
  end
44
44
 
45
45
  def self.arel_node?(value) # :nodoc:
46
- value.is_a?(Arel::Node) || value.is_a?(Arel::Attribute) || value.is_a?(Arel::Nodes::SqlLiteral)
46
+ value.is_a?(Arel::Nodes::Node) || value.is_a?(Arel::Attribute) || value.is_a?(Arel::Nodes::SqlLiteral)
47
47
  end
48
48
 
49
- def self.fetch_attribute(value) # :nodoc:
50
- case value
51
- when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual
52
- if value.left.is_a?(Arel::Attributes::Attribute)
53
- yield value.left
54
- elsif value.right.is_a?(Arel::Attributes::Attribute)
55
- yield value.right
56
- end
49
+ def self.fetch_attribute(value, &block) # :nodoc:
50
+ unless String === value
51
+ value.fetch_attribute(&block)
57
52
  end
58
53
  end
59
-
60
- ## Convenience Alias
61
- Node = Arel::Nodes::Node # :nodoc:
62
54
  end
@@ -7,6 +7,7 @@ module ActiveRecord
7
7
  class MigrationGenerator < Base # :nodoc:
8
8
  argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
9
9
 
10
+ class_option :timestamps, type: :boolean
10
11
  class_option :primary_key_type, type: :string, desc: "The type for primary key"
11
12
  class_option :database, type: :string, aliases: %i(--db), desc: "The database for your migration. By default, the current environment's primary database is used."
12
13
 
@@ -6,6 +6,8 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
6
6
  t.string :password_digest<%= attribute.inject_options %>
7
7
  <% elsif attribute.token? -%>
8
8
  t.string :<%= attribute.name %><%= attribute.inject_options %>
9
+ <% elsif attribute.reference? -%>
10
+ t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %><%= foreign_key_type %>
9
11
  <% elsif !attribute.virtual? -%>
10
12
  t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
11
13
  <% end -%>
@@ -3,7 +3,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
3
3
  def change
4
4
  <% attributes.each do |attribute| -%>
5
5
  <%- if attribute.reference? -%>
6
- add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
6
+ add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %><%= foreign_key_type %>
7
7
  <%- elsif attribute.token? -%>
8
8
  add_column :<%= table_name %>, :<%= attribute.name %>, :string<%= attribute.inject_options %>
9
9
  add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>, unique: true
@@ -20,7 +20,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
20
20
  create_join_table :<%= join_tables.first %>, :<%= join_tables.second %> do |t|
21
21
  <%- attributes.each do |attribute| -%>
22
22
  <%- if attribute.reference? -%>
23
- t.references :<%= attribute.name %><%= attribute.inject_options %>
23
+ t.references :<%= attribute.name %><%= attribute.inject_options %><%= foreign_key_type %>
24
24
  <%- elsif !attribute.virtual? -%>
25
25
  <%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %>
26
26
  <%- end -%>
@@ -32,7 +32,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
32
32
  <% attributes.each do |attribute| -%>
33
33
  <%- if migration_action -%>
34
34
  <%- if attribute.reference? -%>
35
- remove_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
35
+ remove_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %><%= foreign_key_type %>
36
36
  <%- else -%>
37
37
  <%- if attribute.has_index? -%>
38
38
  remove_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
@@ -22,6 +22,11 @@ module ActiveRecord
22
22
  ", id: :#{key_type}" if key_type
23
23
  end
24
24
 
25
+ def foreign_key_type
26
+ key_type = options[:primary_key_type]
27
+ ", type: :#{key_type}" if key_type
28
+ end
29
+
25
30
  def db_migrate_path
26
31
  if defined?(Rails.application) && Rails.application
27
32
  configured_migrate_path || default_migrate_path
@@ -38,7 +43,7 @@ module ActiveRecord
38
43
  return unless database = options[:database]
39
44
  config = ActiveRecord::Base.configurations.configs_for(
40
45
  env_name: Rails.env,
41
- spec_name: database,
46
+ name: database
42
47
  )
43
48
  config&.migrations_paths
44
49
  end
@@ -18,12 +18,13 @@ module ActiveRecord
18
18
 
19
19
  # creates the migration file for the model.
20
20
  def create_migration_file
21
- return unless options[:migration] && options[:parent].nil?
21
+ return if skip_migration_creation?
22
22
  attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false
23
23
  migration_template "../../migration/templates/create_table_migration.rb", File.join(db_migrate_path, "create_#{table_name}.rb")
24
24
  end
25
25
 
26
26
  def create_model_file
27
+ generate_abstract_class if database && !parent
27
28
  template "model.rb", File.join("app/models", class_path, "#{file_name}.rb")
28
29
  end
29
30
 
@@ -35,13 +36,49 @@ module ActiveRecord
35
36
  hook_for :test_framework
36
37
 
37
38
  private
39
+ # Skip creating migration file if:
40
+ # - options parent is present and database option is not present
41
+ # - migrations option is nil or false
42
+ def skip_migration_creation?
43
+ parent && !database || !migration
44
+ end
45
+
38
46
  def attributes_with_index
39
47
  attributes.select { |a| !a.reference? && a.has_index? }
40
48
  end
41
49
 
42
50
  # Used by the migration template to determine the parent name of the model
43
51
  def parent_class_name
44
- options[:parent] || "ApplicationRecord"
52
+ if parent
53
+ parent
54
+ elsif database
55
+ abstract_class_name
56
+ else
57
+ "ApplicationRecord"
58
+ end
59
+ end
60
+
61
+ def generate_abstract_class
62
+ path = File.join("app/models", "#{database.underscore}_record.rb")
63
+ return if File.exist?(path)
64
+
65
+ template "abstract_base_class.rb", path
66
+ end
67
+
68
+ def abstract_class_name
69
+ "#{database.camelize}Record"
70
+ end
71
+
72
+ def database
73
+ options[:database]
74
+ end
75
+
76
+ def parent
77
+ options[:parent]
78
+ end
79
+
80
+ def migration
81
+ options[:migration]
45
82
  end
46
83
  end
47
84
  end
@@ -0,0 +1,7 @@
1
+ <% module_namespacing do -%>
2
+ class <%= abstract_class_name %> < ApplicationRecord
3
+ self.abstract_class = true
4
+
5
+ connects_to database: { <%= ActiveRecord::Base.writing_role %>: :<%= database -%> }
6
+ end
7
+ <% end -%>