activerecord 7.1.5.1 → 7.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +836 -2203
  3. data/README.rdoc +16 -16
  4. data/examples/performance.rb +2 -2
  5. data/lib/active_record/association_relation.rb +1 -1
  6. data/lib/active_record/associations/alias_tracker.rb +31 -23
  7. data/lib/active_record/associations/association.rb +15 -8
  8. data/lib/active_record/associations/belongs_to_association.rb +31 -8
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  10. data/lib/active_record/associations/builder/belongs_to.rb +1 -0
  11. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
  12. data/lib/active_record/associations/builder/has_many.rb +3 -4
  13. data/lib/active_record/associations/builder/has_one.rb +3 -4
  14. data/lib/active_record/associations/collection_association.rb +16 -8
  15. data/lib/active_record/associations/collection_proxy.rb +14 -1
  16. data/lib/active_record/associations/errors.rb +265 -0
  17. data/lib/active_record/associations/has_many_association.rb +1 -1
  18. data/lib/active_record/associations/has_many_through_association.rb +7 -1
  19. data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
  20. data/lib/active_record/associations/nested_error.rb +47 -0
  21. data/lib/active_record/associations/preloader/association.rb +2 -1
  22. data/lib/active_record/associations/preloader/branch.rb +7 -1
  23. data/lib/active_record/associations/preloader/through_association.rb +1 -3
  24. data/lib/active_record/associations/singular_association.rb +6 -0
  25. data/lib/active_record/associations/through_association.rb +1 -1
  26. data/lib/active_record/associations.rb +59 -292
  27. data/lib/active_record/attribute_assignment.rb +0 -2
  28. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  29. data/lib/active_record/attribute_methods/primary_key.rb +23 -55
  30. data/lib/active_record/attribute_methods/read.rb +1 -13
  31. data/lib/active_record/attribute_methods/serialization.rb +5 -25
  32. data/lib/active_record/attribute_methods/time_zone_conversion.rb +7 -6
  33. data/lib/active_record/attribute_methods.rb +71 -75
  34. data/lib/active_record/attributes.rb +93 -68
  35. data/lib/active_record/autosave_association.rb +25 -32
  36. data/lib/active_record/base.rb +4 -5
  37. data/lib/active_record/callbacks.rb +1 -1
  38. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +24 -107
  39. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -0
  40. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +294 -72
  41. data/lib/active_record/connection_adapters/abstract/database_statements.rb +34 -17
  42. data/lib/active_record/connection_adapters/abstract/query_cache.rb +201 -75
  43. data/lib/active_record/connection_adapters/abstract/quoting.rb +65 -91
  44. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +6 -2
  45. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +18 -6
  46. data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -62
  47. data/lib/active_record/connection_adapters/abstract_adapter.rb +56 -47
  48. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +53 -15
  49. data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
  50. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -49
  51. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +6 -0
  52. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +19 -18
  53. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -23
  54. data/lib/active_record/connection_adapters/pool_config.rb +7 -6
  55. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +27 -4
  56. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  57. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  58. data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
  59. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +30 -8
  60. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +1 -1
  61. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +16 -12
  62. data/lib/active_record/connection_adapters/postgresql_adapter.rb +36 -26
  63. data/lib/active_record/connection_adapters/schema_cache.rb +123 -128
  64. data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
  65. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -6
  66. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -46
  67. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  68. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
  69. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  70. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +26 -2
  71. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +133 -78
  72. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +15 -15
  73. data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -48
  74. data/lib/active_record/connection_adapters.rb +121 -0
  75. data/lib/active_record/connection_handling.rb +68 -49
  76. data/lib/active_record/core.rb +113 -45
  77. data/lib/active_record/counter_cache.rb +19 -10
  78. data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
  79. data/lib/active_record/database_configurations/database_config.rb +19 -4
  80. data/lib/active_record/database_configurations/hash_config.rb +38 -34
  81. data/lib/active_record/database_configurations/url_config.rb +20 -1
  82. data/lib/active_record/database_configurations.rb +1 -1
  83. data/lib/active_record/delegated_type.rb +42 -18
  84. data/lib/active_record/dynamic_matchers.rb +2 -2
  85. data/lib/active_record/encryption/encryptable_record.rb +4 -4
  86. data/lib/active_record/encryption/encrypted_attribute_type.rb +25 -5
  87. data/lib/active_record/encryption/encryptor.rb +35 -19
  88. data/lib/active_record/encryption/key_provider.rb +1 -1
  89. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  90. data/lib/active_record/encryption/message_serializer.rb +4 -0
  91. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  92. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  93. data/lib/active_record/enum.rb +31 -13
  94. data/lib/active_record/errors.rb +49 -23
  95. data/lib/active_record/explain.rb +13 -24
  96. data/lib/active_record/fixture_set/table_row.rb +19 -2
  97. data/lib/active_record/fixtures.rb +37 -31
  98. data/lib/active_record/future_result.rb +8 -4
  99. data/lib/active_record/gem_version.rb +3 -3
  100. data/lib/active_record/inheritance.rb +4 -2
  101. data/lib/active_record/insert_all.rb +18 -15
  102. data/lib/active_record/integration.rb +4 -1
  103. data/lib/active_record/internal_metadata.rb +48 -34
  104. data/lib/active_record/locking/optimistic.rb +7 -6
  105. data/lib/active_record/log_subscriber.rb +0 -21
  106. data/lib/active_record/message_pack.rb +1 -1
  107. data/lib/active_record/migration/command_recorder.rb +2 -3
  108. data/lib/active_record/migration/compatibility.rb +5 -3
  109. data/lib/active_record/migration/default_strategy.rb +4 -5
  110. data/lib/active_record/migration/pending_migration_connection.rb +2 -2
  111. data/lib/active_record/migration.rb +87 -77
  112. data/lib/active_record/model_schema.rb +31 -68
  113. data/lib/active_record/nested_attributes.rb +11 -3
  114. data/lib/active_record/normalization.rb +3 -7
  115. data/lib/active_record/persistence.rb +30 -352
  116. data/lib/active_record/query_cache.rb +19 -8
  117. data/lib/active_record/query_logs.rb +19 -0
  118. data/lib/active_record/querying.rb +25 -13
  119. data/lib/active_record/railtie.rb +39 -57
  120. data/lib/active_record/railties/controller_runtime.rb +13 -4
  121. data/lib/active_record/railties/databases.rake +42 -44
  122. data/lib/active_record/reflection.rb +98 -36
  123. data/lib/active_record/relation/batches/batch_enumerator.rb +15 -2
  124. data/lib/active_record/relation/batches.rb +14 -8
  125. data/lib/active_record/relation/calculations.rb +127 -89
  126. data/lib/active_record/relation/delegation.rb +8 -11
  127. data/lib/active_record/relation/finder_methods.rb +30 -15
  128. data/lib/active_record/relation/merger.rb +4 -6
  129. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  130. data/lib/active_record/relation/predicate_builder/association_query_value.rb +10 -2
  131. data/lib/active_record/relation/predicate_builder.rb +3 -3
  132. data/lib/active_record/relation/query_attribute.rb +1 -1
  133. data/lib/active_record/relation/query_methods.rb +238 -65
  134. data/lib/active_record/relation/record_fetch_warning.rb +3 -0
  135. data/lib/active_record/relation/spawn_methods.rb +2 -18
  136. data/lib/active_record/relation/where_clause.rb +15 -21
  137. data/lib/active_record/relation.rb +508 -74
  138. data/lib/active_record/result.rb +31 -44
  139. data/lib/active_record/runtime_registry.rb +39 -0
  140. data/lib/active_record/sanitization.rb +24 -19
  141. data/lib/active_record/schema.rb +8 -6
  142. data/lib/active_record/schema_dumper.rb +48 -20
  143. data/lib/active_record/schema_migration.rb +30 -14
  144. data/lib/active_record/scoping/named.rb +1 -0
  145. data/lib/active_record/secure_token.rb +3 -3
  146. data/lib/active_record/signed_id.rb +27 -7
  147. data/lib/active_record/statement_cache.rb +7 -7
  148. data/lib/active_record/table_metadata.rb +1 -10
  149. data/lib/active_record/tasks/database_tasks.rb +69 -41
  150. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  151. data/lib/active_record/tasks/postgresql_database_tasks.rb +8 -1
  152. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -1
  153. data/lib/active_record/test_fixtures.rb +86 -89
  154. data/lib/active_record/testing/query_assertions.rb +121 -0
  155. data/lib/active_record/timestamp.rb +2 -2
  156. data/lib/active_record/token_for.rb +22 -12
  157. data/lib/active_record/touch_later.rb +1 -1
  158. data/lib/active_record/transaction.rb +132 -0
  159. data/lib/active_record/transactions.rb +73 -15
  160. data/lib/active_record/translation.rb +0 -2
  161. data/lib/active_record/type/serialized.rb +1 -3
  162. data/lib/active_record/type_caster/connection.rb +4 -4
  163. data/lib/active_record/validations/associated.rb +9 -3
  164. data/lib/active_record/validations/uniqueness.rb +15 -10
  165. data/lib/active_record/validations.rb +4 -1
  166. data/lib/active_record.rb +148 -39
  167. data/lib/arel/alias_predication.rb +1 -1
  168. data/lib/arel/collectors/bind.rb +3 -1
  169. data/lib/arel/collectors/composite.rb +7 -0
  170. data/lib/arel/collectors/sql_string.rb +1 -1
  171. data/lib/arel/collectors/substitute_binds.rb +1 -1
  172. data/lib/arel/crud.rb +2 -0
  173. data/lib/arel/delete_manager.rb +5 -0
  174. data/lib/arel/nodes/binary.rb +0 -6
  175. data/lib/arel/nodes/bound_sql_literal.rb +9 -5
  176. data/lib/arel/nodes/delete_statement.rb +4 -2
  177. data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
  178. data/lib/arel/nodes/node.rb +4 -3
  179. data/lib/arel/nodes/sql_literal.rb +7 -0
  180. data/lib/arel/nodes/update_statement.rb +4 -2
  181. data/lib/arel/nodes.rb +2 -2
  182. data/lib/arel/predications.rb +1 -1
  183. data/lib/arel/select_manager.rb +7 -3
  184. data/lib/arel/tree_manager.rb +3 -2
  185. data/lib/arel/update_manager.rb +7 -1
  186. data/lib/arel/visitors/dot.rb +3 -0
  187. data/lib/arel/visitors/mysql.rb +9 -4
  188. data/lib/arel/visitors/postgresql.rb +1 -12
  189. data/lib/arel/visitors/sqlite.rb +25 -0
  190. data/lib/arel/visitors/to_sql.rb +31 -16
  191. data/lib/arel.rb +7 -3
  192. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  193. metadata +18 -15
@@ -52,8 +52,9 @@ module Arel # :nodoc: all
52
52
 
53
53
  def to_sql(engine = Table.engine)
54
54
  collector = Arel::Collectors::SQLString.new
55
- collector = engine.connection.visitor.accept @ast, collector
56
- collector.value
55
+ engine.with_connection do |connection|
56
+ connection.visitor.accept(@ast, collector).value
57
+ end
57
58
  end
58
59
 
59
60
  def initialize_copy(other)
@@ -16,7 +16,8 @@ module Arel # :nodoc: all
16
16
  end
17
17
 
18
18
  def set(values)
19
- if String === values
19
+ case values
20
+ when String, Nodes::BoundSqlLiteral
20
21
  @ast.values = [values]
21
22
  else
22
23
  @ast.values = values.map { |column, value|
@@ -44,5 +45,10 @@ module Arel # :nodoc: all
44
45
  @ast.havings << expr
45
46
  self
46
47
  end
48
+
49
+ def comment(value)
50
+ @ast.comment = value
51
+ self
52
+ end
47
53
  end
48
54
  end
@@ -153,6 +153,7 @@ module Arel # :nodoc: all
153
153
  visit_edge o, "orders"
154
154
  visit_edge o, "limit"
155
155
  visit_edge o, "offset"
156
+ visit_edge o, "comment"
156
157
  visit_edge o, "key"
157
158
  end
158
159
 
@@ -162,6 +163,7 @@ module Arel # :nodoc: all
162
163
  visit_edge o, "orders"
163
164
  visit_edge o, "limit"
164
165
  visit_edge o, "offset"
166
+ visit_edge o, "comment"
165
167
  visit_edge o, "key"
166
168
  end
167
169
 
@@ -191,6 +193,7 @@ module Arel # :nodoc: all
191
193
  end
192
194
  end
193
195
  alias :visit_Arel_Nodes_And :visit__children
196
+ alias :visit_Arel_Nodes_Or :visit__children
194
197
  alias :visit_Arel_Nodes_With :visit__children
195
198
 
196
199
  def visit_String(o)
@@ -27,7 +27,7 @@ module Arel # :nodoc: all
27
27
  end
28
28
 
29
29
  def visit_Arel_Nodes_SelectCore(o, collector)
30
- o.froms ||= Arel.sql("DUAL")
30
+ o.froms ||= Arel.sql("DUAL", retryable: true)
31
31
  super
32
32
  end
33
33
 
@@ -59,9 +59,14 @@ module Arel # :nodoc: all
59
59
  infix_value o, collector, " NOT REGEXP "
60
60
  end
61
61
 
62
- # no-op
63
62
  def visit_Arel_Nodes_NullsFirst(o, collector)
64
- visit o.expr, collector
63
+ visit(o.expr.expr, collector) << " IS NOT NULL, "
64
+ visit(o.expr, collector)
65
+ end
66
+
67
+ def visit_Arel_Nodes_NullsLast(o, collector)
68
+ visit(o.expr.expr, collector) << " IS NULL, "
69
+ visit(o.expr, collector)
65
70
  end
66
71
 
67
72
  def visit_Arel_Nodes_Cte(o, collector)
@@ -98,7 +103,7 @@ module Arel # :nodoc: all
98
103
  Nodes::SelectStatement.new.tap do |stmt|
99
104
  core = stmt.cores.last
100
105
  core.froms = Nodes::Grouping.new(subselect).as("__active_record_temp")
101
- core.projections = [Arel.sql(quote_column_name(key.name))]
106
+ core.projections = [Arel.sql(quote_column_name(key.name), retryable: true)]
102
107
  end
103
108
  end
104
109
  end
@@ -63,7 +63,7 @@ module Arel # :nodoc: all
63
63
 
64
64
  def visit_Arel_Nodes_Lateral(o, collector)
65
65
  collector << "LATERAL "
66
- grouping_parentheses o, collector
66
+ grouping_parentheses o.expr, collector
67
67
  end
68
68
 
69
69
  def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
@@ -83,17 +83,6 @@ module Arel # :nodoc: all
83
83
 
84
84
  def bind_block; BIND_BLOCK; end
85
85
 
86
- # Used by Lateral visitor to enclose select queries in parentheses
87
- def grouping_parentheses(o, collector)
88
- if o.expr.is_a? Nodes::SelectStatement
89
- collector << "("
90
- visit o.expr, collector
91
- collector << ")"
92
- else
93
- visit o.expr, collector
94
- end
95
- end
96
-
97
86
  # Utilized by GroupingSet, Cube & RollUp visitors to
98
87
  # handle grouping aggregation semantics
99
88
  def grouping_array_or_grouping_element(o, collector)
@@ -33,6 +33,31 @@ module Arel # :nodoc: all
33
33
  collector << " IS NOT "
34
34
  visit o.right, collector
35
35
  end
36
+
37
+ # Queries used in UNION should not be wrapped by parentheses,
38
+ # because it is an invalid syntax in SQLite.
39
+ def infix_value_with_paren(o, collector, value, suppress_parens = false)
40
+ collector << "( " unless suppress_parens
41
+
42
+ left = o.left.is_a?(Nodes::Grouping) ? o.left.expr : o.left
43
+ collector = if left.class == o.class
44
+ infix_value_with_paren(left, collector, value, true)
45
+ else
46
+ grouping_parentheses left, collector, false
47
+ end
48
+
49
+ collector << value
50
+
51
+ right = o.right.is_a?(Nodes::Grouping) ? o.right.expr : o.right
52
+ collector = if right.class == o.class
53
+ infix_value_with_paren(right, collector, value, true)
54
+ else
55
+ grouping_parentheses right, collector, false
56
+ end
57
+
58
+ collector << " )" unless suppress_parens
59
+ collector
60
+ end
36
61
  end
37
62
  end
38
63
  end
@@ -20,6 +20,7 @@ module Arel # :nodoc: all
20
20
 
21
21
  private
22
22
  def visit_Arel_Nodes_DeleteStatement(o, collector)
23
+ collector.retryable = false
23
24
  o = prepare_delete_statement(o)
24
25
 
25
26
  if has_join_sources?(o)
@@ -34,9 +35,11 @@ module Arel # :nodoc: all
34
35
  collect_nodes_for o.wheres, collector, " WHERE ", " AND "
35
36
  collect_nodes_for o.orders, collector, " ORDER BY "
36
37
  maybe_visit o.limit, collector
38
+ maybe_visit o.comment, collector
37
39
  end
38
40
 
39
41
  def visit_Arel_Nodes_UpdateStatement(o, collector)
42
+ collector.retryable = false
40
43
  o = prepare_update_statement(o)
41
44
 
42
45
  collector << "UPDATE "
@@ -46,9 +49,11 @@ module Arel # :nodoc: all
46
49
  collect_nodes_for o.wheres, collector, " WHERE ", " AND "
47
50
  collect_nodes_for o.orders, collector, " ORDER BY "
48
51
  maybe_visit o.limit, collector
52
+ maybe_visit o.comment, collector
49
53
  end
50
54
 
51
55
  def visit_Arel_Nodes_InsertStatement(o, collector)
56
+ collector.retryable = false
52
57
  collector << "INSERT INTO "
53
58
  collector = visit o.relation, collector
54
59
 
@@ -381,6 +386,7 @@ module Arel # :nodoc: all
381
386
  end
382
387
 
383
388
  def visit_Arel_Nodes_NamedFunction(o, collector)
389
+ collector.retryable = false
384
390
  collector << o.name
385
391
  collector << "("
386
392
  collector << "DISTINCT " if o.distinct
@@ -582,10 +588,11 @@ module Arel # :nodoc: all
582
588
  end
583
589
 
584
590
  def visit_Arel_Nodes_In(o, collector)
585
- collector.preparable = false
586
591
  attr, values = o.left, o.right
587
592
 
588
593
  if Array === values
594
+ collector.preparable = false
595
+
589
596
  unless values.empty?
590
597
  values.delete_if { |value| unboundable?(value) }
591
598
  end
@@ -598,10 +605,11 @@ module Arel # :nodoc: all
598
605
  end
599
606
 
600
607
  def visit_Arel_Nodes_NotIn(o, collector)
601
- collector.preparable = false
602
608
  attr, values = o.left, o.right
603
609
 
604
610
  if Array === values
611
+ collector.preparable = false
612
+
605
613
  unless values.empty?
606
614
  values.delete_if { |value| unboundable?(value) }
607
615
  end
@@ -618,18 +626,7 @@ module Arel # :nodoc: all
618
626
  end
619
627
 
620
628
  def visit_Arel_Nodes_Or(o, collector)
621
- stack = [o.right, o.left]
622
-
623
- while o = stack.pop
624
- if o.is_a?(Arel::Nodes::Or)
625
- stack.push o.right, o.left
626
- else
627
- visit o, collector
628
- collector << " OR " unless stack.empty?
629
- end
630
- end
631
-
632
- collector
629
+ inject_join o.children, collector, " OR "
633
630
  end
634
631
 
635
632
  def visit_Arel_Nodes_Assignment(o, collector)
@@ -768,10 +765,12 @@ module Arel # :nodoc: all
768
765
 
769
766
  def visit_Arel_Nodes_SqlLiteral(o, collector)
770
767
  collector.preparable = false
768
+ collector.retryable &&= o.retryable
771
769
  collector << o.to_s
772
770
  end
773
771
 
774
772
  def visit_Arel_Nodes_BoundSqlLiteral(o, collector)
773
+ collector.retryable = false
775
774
  bind_index = 0
776
775
 
777
776
  new_bind = lambda do |value|
@@ -968,18 +967,34 @@ module Arel # :nodoc: all
968
967
  collector = if o.left.class == o.class
969
968
  infix_value_with_paren(o.left, collector, value, true)
970
969
  else
971
- visit o.left, collector
970
+ grouping_parentheses o.left, collector, false
972
971
  end
973
972
  collector << value
974
973
  collector = if o.right.class == o.class
975
974
  infix_value_with_paren(o.right, collector, value, true)
976
975
  else
977
- visit o.right, collector
976
+ grouping_parentheses o.right, collector, false
978
977
  end
979
978
  collector << " )" unless suppress_parens
980
979
  collector
981
980
  end
982
981
 
982
+ # Used by some visitors to enclose select queries in parentheses
983
+ def grouping_parentheses(o, collector, always_wrap_selects = true)
984
+ if o.is_a?(Nodes::SelectStatement) && (always_wrap_selects || require_parentheses?(o))
985
+ collector << "("
986
+ visit o, collector
987
+ collector << ")"
988
+ collector
989
+ else
990
+ visit o, collector
991
+ end
992
+ end
993
+
994
+ def require_parentheses?(o)
995
+ !o.orders.empty? || o.limit || o.offset
996
+ end
997
+
983
998
  def aggregate(name, o, collector)
984
999
  collector << "#{name}("
985
1000
  if o.distinct
data/lib/arel.rb CHANGED
@@ -45,16 +45,20 @@ module Arel
45
45
  # that this behavior only applies when bind value parameters are
46
46
  # supplied in the call; without them, the placeholder tokens have no
47
47
  # special meaning, and will be passed through to the query as-is.
48
- def self.sql(sql_string, *positional_binds, **named_binds)
48
+ #
49
+ # The +:retryable+ option can be used to mark the SQL as safe to retry.
50
+ # Use this option only if the SQL is idempotent, as it could be executed
51
+ # more than once.
52
+ def self.sql(sql_string, *positional_binds, retryable: false, **named_binds)
49
53
  if positional_binds.empty? && named_binds.empty?
50
- Arel::Nodes::SqlLiteral.new sql_string
54
+ Arel::Nodes::SqlLiteral.new(sql_string, retryable: retryable)
51
55
  else
52
56
  Arel::Nodes::BoundSqlLiteral.new sql_string, positional_binds, named_binds
53
57
  end
54
58
  end
55
59
 
56
60
  def self.star # :nodoc:
57
- sql "*"
61
+ sql("*", retryable: true)
58
62
  end
59
63
 
60
64
  def self.arel_node?(value) # :nodoc:
@@ -12,7 +12,10 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
12
12
  t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
13
13
  <% end -%>
14
14
  <% end -%>
15
- <% if options[:timestamps] %>
15
+ <% unless attributes.empty? -%>
16
+
17
+ <% end -%>
18
+ <% if options[:timestamps] -%>
16
19
  t.timestamps
17
20
  <% end -%>
18
21
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.5.1
4
+ version: 7.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-10 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -16,28 +15,28 @@ dependencies:
16
15
  requirements:
17
16
  - - '='
18
17
  - !ruby/object:Gem::Version
19
- version: 7.1.5.1
18
+ version: 7.2.3
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - '='
25
24
  - !ruby/object:Gem::Version
26
- version: 7.1.5.1
25
+ version: 7.2.3
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: activemodel
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - '='
32
31
  - !ruby/object:Gem::Version
33
- version: 7.1.5.1
32
+ version: 7.2.3
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - '='
39
38
  - !ruby/object:Gem::Version
40
- version: 7.1.5.1
39
+ version: 7.2.3
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: timeout
43
42
  requirement: !ruby/object:Gem::Requirement
@@ -85,6 +84,7 @@ files:
85
84
  - lib/active_record/associations/collection_association.rb
86
85
  - lib/active_record/associations/collection_proxy.rb
87
86
  - lib/active_record/associations/disable_joins_association_scope.rb
87
+ - lib/active_record/associations/errors.rb
88
88
  - lib/active_record/associations/foreign_association.rb
89
89
  - lib/active_record/associations/has_many_association.rb
90
90
  - lib/active_record/associations/has_many_through_association.rb
@@ -94,6 +94,7 @@ files:
94
94
  - lib/active_record/associations/join_dependency/join_association.rb
95
95
  - lib/active_record/associations/join_dependency/join_base.rb
96
96
  - lib/active_record/associations/join_dependency/join_part.rb
97
+ - lib/active_record/associations/nested_error.rb
97
98
  - lib/active_record/associations/preloader.rb
98
99
  - lib/active_record/associations/preloader/association.rb
99
100
  - lib/active_record/associations/preloader/batch.rb
@@ -105,6 +106,7 @@ files:
105
106
  - lib/active_record/attribute_assignment.rb
106
107
  - lib/active_record/attribute_methods.rb
107
108
  - lib/active_record/attribute_methods/before_type_cast.rb
109
+ - lib/active_record/attribute_methods/composite_primary_key.rb
108
110
  - lib/active_record/attribute_methods/dirty.rb
109
111
  - lib/active_record/attribute_methods/primary_key.rb
110
112
  - lib/active_record/attribute_methods/query.rb
@@ -240,6 +242,7 @@ files:
240
242
  - lib/active_record/encryption/key_generator.rb
241
243
  - lib/active_record/encryption/key_provider.rb
242
244
  - lib/active_record/encryption/message.rb
245
+ - lib/active_record/encryption/message_pack_message_serializer.rb
243
246
  - lib/active_record/encryption/message_serializer.rb
244
247
  - lib/active_record/encryption/null_encryptor.rb
245
248
  - lib/active_record/encryption/properties.rb
@@ -340,9 +343,11 @@ files:
340
343
  - lib/active_record/tasks/sqlite_database_tasks.rb
341
344
  - lib/active_record/test_databases.rb
342
345
  - lib/active_record/test_fixtures.rb
346
+ - lib/active_record/testing/query_assertions.rb
343
347
  - lib/active_record/timestamp.rb
344
348
  - lib/active_record/token_for.rb
345
349
  - lib/active_record/touch_later.rb
350
+ - lib/active_record/transaction.rb
346
351
  - lib/active_record/transactions.rb
347
352
  - lib/active_record/translation.rb
348
353
  - lib/active_record/type.rb
@@ -386,7 +391,6 @@ files:
386
391
  - lib/arel/insert_manager.rb
387
392
  - lib/arel/math.rb
388
393
  - lib/arel/nodes.rb
389
- - lib/arel/nodes/and.rb
390
394
  - lib/arel/nodes/ascending.rb
391
395
  - lib/arel/nodes/binary.rb
392
396
  - lib/arel/nodes/bind_param.rb
@@ -415,6 +419,7 @@ files:
415
419
  - lib/arel/nodes/leading_join.rb
416
420
  - lib/arel/nodes/matches.rb
417
421
  - lib/arel/nodes/named_function.rb
422
+ - lib/arel/nodes/nary.rb
418
423
  - lib/arel/nodes/node.rb
419
424
  - lib/arel/nodes/node_expression.rb
420
425
  - lib/arel/nodes/ordering.rb
@@ -470,12 +475,11 @@ licenses:
470
475
  - MIT
471
476
  metadata:
472
477
  bug_tracker_uri: https://github.com/rails/rails/issues
473
- changelog_uri: https://github.com/rails/rails/blob/v7.1.5.1/activerecord/CHANGELOG.md
474
- documentation_uri: https://api.rubyonrails.org/v7.1.5.1/
478
+ changelog_uri: https://github.com/rails/rails/blob/v7.2.3/activerecord/CHANGELOG.md
479
+ documentation_uri: https://api.rubyonrails.org/v7.2.3/
475
480
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
476
- source_code_uri: https://github.com/rails/rails/tree/v7.1.5.1/activerecord
481
+ source_code_uri: https://github.com/rails/rails/tree/v7.2.3/activerecord
477
482
  rubygems_mfa_required: 'true'
478
- post_install_message:
479
483
  rdoc_options:
480
484
  - "--main"
481
485
  - README.rdoc
@@ -485,15 +489,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
485
489
  requirements:
486
490
  - - ">="
487
491
  - !ruby/object:Gem::Version
488
- version: 2.7.0
492
+ version: 3.1.0
489
493
  required_rubygems_version: !ruby/object:Gem::Requirement
490
494
  requirements:
491
495
  - - ">="
492
496
  - !ruby/object:Gem::Version
493
497
  version: '0'
494
498
  requirements: []
495
- rubygems_version: 3.5.22
496
- signing_key:
499
+ rubygems_version: 3.6.9
497
500
  specification_version: 4
498
501
  summary: Object-relational mapper framework (part of Rails).
499
502
  test_files: []