activerecord 6.0.0.beta1 → 6.0.0.beta2

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +99 -2
  3. data/lib/active_record.rb +7 -0
  4. data/lib/active_record/associations/association.rb +17 -0
  5. data/lib/active_record/associations/collection_association.rb +5 -6
  6. data/lib/active_record/associations/collection_proxy.rb +12 -41
  7. data/lib/active_record/associations/has_many_association.rb +1 -9
  8. data/lib/active_record/associations/join_dependency/join_association.rb +11 -6
  9. data/lib/active_record/associations/preloader/association.rb +3 -4
  10. data/lib/active_record/associations/preloader/through_association.rb +9 -20
  11. data/lib/active_record/callbacks.rb +3 -3
  12. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +25 -12
  13. data/lib/active_record/connection_adapters/abstract/database_statements.rb +17 -9
  14. data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -1
  15. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +5 -2
  16. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +47 -33
  17. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +16 -8
  18. data/lib/active_record/connection_adapters/abstract/transaction.rb +5 -2
  19. data/lib/active_record/connection_adapters/abstract_adapter.rb +6 -4
  20. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +28 -65
  21. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +1 -1
  22. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  23. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  24. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +59 -1
  25. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  26. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
  27. data/lib/active_record/connection_adapters/postgresql/quoting.rb +1 -1
  28. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +36 -0
  29. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +98 -89
  30. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -27
  31. data/lib/active_record/connection_adapters/postgresql_adapter.rb +30 -0
  32. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +27 -1
  33. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +8 -5
  34. data/lib/active_record/connection_handling.rb +9 -4
  35. data/lib/active_record/core.rb +13 -1
  36. data/lib/active_record/database_configurations.rb +30 -10
  37. data/lib/active_record/database_configurations/hash_config.rb +1 -1
  38. data/lib/active_record/database_configurations/url_config.rb +9 -4
  39. data/lib/active_record/errors.rb +17 -12
  40. data/lib/active_record/gem_version.rb +1 -1
  41. data/lib/active_record/inheritance.rb +1 -1
  42. data/lib/active_record/middleware/database_selector.rb +75 -0
  43. data/lib/active_record/middleware/database_selector/resolver.rb +90 -0
  44. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  45. data/lib/active_record/migration.rb +1 -1
  46. data/lib/active_record/migration/compatibility.rb +62 -63
  47. data/lib/active_record/persistence.rb +6 -6
  48. data/lib/active_record/querying.rb +2 -3
  49. data/lib/active_record/railtie.rb +9 -0
  50. data/lib/active_record/railties/collection_cache_association_loading.rb +3 -3
  51. data/lib/active_record/reflection.rb +15 -29
  52. data/lib/active_record/relation.rb +86 -15
  53. data/lib/active_record/relation/calculations.rb +2 -4
  54. data/lib/active_record/relation/delegation.rb +1 -1
  55. data/lib/active_record/relation/finder_methods.rb +8 -4
  56. data/lib/active_record/relation/query_attribute.rb +5 -3
  57. data/lib/active_record/relation/query_methods.rb +28 -8
  58. data/lib/active_record/relation/spawn_methods.rb +1 -1
  59. data/lib/active_record/relation/where_clause.rb +1 -5
  60. data/lib/active_record/scoping.rb +6 -7
  61. data/lib/active_record/scoping/default.rb +1 -8
  62. data/lib/active_record/scoping/named.rb +9 -1
  63. data/lib/active_record/test_fixtures.rb +2 -2
  64. data/lib/active_record/timestamp.rb +9 -3
  65. data/lib/active_record/validations/uniqueness.rb +3 -1
  66. data/lib/arel.rb +7 -0
  67. data/lib/arel/nodes/and.rb +1 -1
  68. data/lib/arel/nodes/case.rb +1 -1
  69. metadata +11 -8
@@ -95,7 +95,7 @@ module ActiveRecord
95
95
  #
96
96
  # private
97
97
  # def delete_parents
98
- # self.class.where(parent_id: id).delete_all
98
+ # self.class.delete_by(parent_id: id)
99
99
  # end
100
100
  # end
101
101
  #
@@ -324,7 +324,7 @@ module ActiveRecord
324
324
 
325
325
  private
326
326
 
327
- def create_or_update(*)
327
+ def create_or_update(**)
328
328
  _run_save_callbacks { super }
329
329
  end
330
330
 
@@ -332,7 +332,7 @@ module ActiveRecord
332
332
  _run_create_callbacks { super }
333
333
  end
334
334
 
335
- def _update_record(*)
335
+ def _update_record
336
336
  _run_update_callbacks { super }
337
337
  end
338
338
  end
@@ -185,7 +185,7 @@ module ActiveRecord
185
185
  def wait_poll(timeout)
186
186
  @num_waiting += 1
187
187
 
188
- t0 = Time.now
188
+ t0 = Concurrent.monotonic_time
189
189
  elapsed = 0
190
190
  loop do
191
191
  ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
@@ -194,7 +194,7 @@ module ActiveRecord
194
194
 
195
195
  return remove if any?
196
196
 
197
- elapsed = Time.now - t0
197
+ elapsed = Concurrent.monotonic_time - t0
198
198
  if elapsed >= timeout
199
199
  msg = "could not obtain a connection from the pool within %0.3f seconds (waited %0.3f seconds); all pooled connections were in use" %
200
200
  [timeout, elapsed]
@@ -686,13 +686,13 @@ module ActiveRecord
686
686
  end
687
687
 
688
688
  newly_checked_out = []
689
- timeout_time = Time.now + (@checkout_timeout * 2)
689
+ timeout_time = Concurrent.monotonic_time + (@checkout_timeout * 2)
690
690
 
691
691
  @available.with_a_bias_for(Thread.current) do
692
692
  loop do
693
693
  synchronize do
694
694
  return if collected_conns.size == @connections.size && @now_connecting == 0
695
- remaining_timeout = timeout_time - Time.now
695
+ remaining_timeout = timeout_time - Concurrent.monotonic_time
696
696
  remaining_timeout = 0 if remaining_timeout < 0
697
697
  conn = checkout_for_exclusive_access(remaining_timeout)
698
698
  collected_conns << conn
@@ -915,6 +915,16 @@ module ActiveRecord
915
915
  # about the model. The model needs to pass a specification name to the handler,
916
916
  # in order to look up the correct connection pool.
917
917
  class ConnectionHandler
918
+ def self.create_owner_to_pool # :nodoc:
919
+ Concurrent::Map.new(initial_capacity: 2) do |h, k|
920
+ # Discard the parent's connection pools immediately; we have no need
921
+ # of them
922
+ discard_unowned_pools(h)
923
+
924
+ h[k] = Concurrent::Map.new(initial_capacity: 2)
925
+ end
926
+ end
927
+
918
928
  def self.unowned_pool_finalizer(pid_map) # :nodoc:
919
929
  lambda do |_|
920
930
  discard_unowned_pools(pid_map)
@@ -929,13 +939,7 @@ module ActiveRecord
929
939
 
930
940
  def initialize
931
941
  # These caches are keyed by spec.name (ConnectionSpecification#name).
932
- @owner_to_pool = Concurrent::Map.new(initial_capacity: 2) do |h, k|
933
- # Discard the parent's connection pools immediately; we have no need
934
- # of them
935
- ConnectionHandler.discard_unowned_pools(h)
936
-
937
- h[k] = Concurrent::Map.new(initial_capacity: 2)
938
- end
942
+ @owner_to_pool = ConnectionHandler.create_owner_to_pool
939
943
 
940
944
  # Backup finalizer: if the forked child never needed a pool, the above
941
945
  # early discard has not occurred
@@ -1006,7 +1010,16 @@ module ActiveRecord
1006
1010
  # for (not necessarily the current class).
1007
1011
  def retrieve_connection(spec_name) #:nodoc:
1008
1012
  pool = retrieve_connection_pool(spec_name)
1009
- raise ConnectionNotEstablished, "No connection pool with '#{spec_name}' found." unless pool
1013
+
1014
+ unless pool
1015
+ # multiple database application
1016
+ if ActiveRecord::Base.connection_handler != ActiveRecord::Base.default_connection_handler
1017
+ raise ConnectionNotEstablished, "No connection pool with '#{spec_name}' found for the '#{ActiveRecord::Base.current_role}' role."
1018
+ else
1019
+ raise ConnectionNotEstablished, "No connection pool with '#{spec_name}' found."
1020
+ end
1021
+ end
1022
+
1010
1023
  pool.connection
1011
1024
  end
1012
1025
 
@@ -20,9 +20,22 @@ module ActiveRecord
20
20
  raise "Passing bind parameters with an arel AST is forbidden. " \
21
21
  "The values must be stored on the AST directly"
22
22
  end
23
- sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
24
- [sql.freeze, binds || []]
23
+
24
+ if prepared_statements
25
+ sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
26
+
27
+ if binds.length > bind_params_length
28
+ unprepared_statement do
29
+ sql, binds = to_sql_and_binds(arel_or_sql_string)
30
+ visitor.preparable = false
31
+ end
32
+ end
33
+ else
34
+ sql = visitor.compile(arel_or_sql_string.ast, collector)
35
+ end
36
+ [sql.freeze, binds]
25
37
  else
38
+ visitor.preparable = false if prepared_statements
26
39
  [arel_or_sql_string.dup.freeze, binds]
27
40
  end
28
41
  end
@@ -47,13 +60,8 @@ module ActiveRecord
47
60
  arel = arel_from_relation(arel)
48
61
  sql, binds = to_sql_and_binds(arel, binds)
49
62
 
50
- if !prepared_statements || (arel.is_a?(String) && preparable.nil?)
51
- preparable = false
52
- elsif binds.length > bind_params_length
53
- sql, binds = unprepared_statement { to_sql_and_binds(arel) }
54
- preparable = false
55
- else
56
- preparable = visitor.preparable
63
+ if preparable.nil?
64
+ preparable = prepared_statements ? visitor.preparable : false
57
65
  end
58
66
 
59
67
  if prepared_statements && preparable
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  method_names.each do |method_name|
18
18
  base.class_eval <<-end_code, __FILE__, __LINE__ + 1
19
19
  def #{method_name}(*)
20
- clear_query_cache if @query_cache_enabled
20
+ ActiveRecord::Base.clear_query_caches_for_current_thread if @query_cache_enabled
21
21
  super
22
22
  end
23
23
  end_code
@@ -96,6 +96,11 @@ module ActiveRecord
96
96
  if @query_cache_enabled && !locked?(arel)
97
97
  arel = arel_from_relation(arel)
98
98
  sql, binds = to_sql_and_binds(arel, binds)
99
+
100
+ if preparable.nil?
101
+ preparable = prepared_statements ? visitor.preparable : false
102
+ end
103
+
99
104
  cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
100
105
  else
101
106
  super
@@ -15,7 +15,7 @@ module ActiveRecord
15
15
  end
16
16
 
17
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_in_create?, :foreign_key_options,
18
+ :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options,
19
19
  to: :@conn, private: true
20
20
 
21
21
  private
@@ -50,7 +50,7 @@ module ActiveRecord
50
50
  statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
51
51
  end
52
52
 
53
- if supports_foreign_keys_in_create?
53
+ if supports_foreign_keys?
54
54
  statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
55
55
  end
56
56
 
@@ -127,6 +127,9 @@ module ActiveRecord
127
127
  end
128
128
 
129
129
  def foreign_key_in_create(from_table, to_table, options)
130
+ prefix = ActiveRecord::Base.table_name_prefix
131
+ suffix = ActiveRecord::Base.table_name_suffix
132
+ to_table = "#{prefix}#{to_table}#{suffix}"
130
133
  options = foreign_key_options(from_table, to_table, options)
131
134
  accept ForeignKeyDefinition.new(from_table, to_table, options)
132
135
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/deprecation"
4
-
5
3
  module ActiveRecord
6
4
  module ConnectionAdapters #:nodoc:
7
5
  # Abstract representation of an index definition on a table. Instances of
@@ -104,7 +102,7 @@ module ActiveRecord
104
102
  alias validated? validate?
105
103
 
106
104
  def export_name_on_schema_dump?
107
- name !~ ActiveRecord::SchemaDumper.fk_ignore_pattern
105
+ !ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
108
106
  end
109
107
 
110
108
  def defined_for?(to_table_ord = nil, to_table: nil, **options)
@@ -200,41 +198,44 @@ module ActiveRecord
200
198
  end
201
199
 
202
200
  module ColumnMethods
201
+ extend ActiveSupport::Concern
202
+
203
203
  # Appends a primary key definition to the table definition.
204
204
  # Can be called multiple times, but this is probably not a good idea.
205
205
  def primary_key(name, type = :primary_key, **options)
206
206
  column(name, type, options.merge(primary_key: true))
207
207
  end
208
208
 
209
+ ##
210
+ # :method: column
211
+ # :call-seq: column(name, type, **options)
212
+ #
209
213
  # Appends a column or columns of a specified type.
210
214
  #
211
215
  # t.string(:goat)
212
216
  # t.string(:goat, :sheep)
213
217
  #
214
218
  # See TableDefinition#column
215
- [
216
- :bigint,
217
- :binary,
218
- :boolean,
219
- :date,
220
- :datetime,
221
- :decimal,
222
- :float,
223
- :integer,
224
- :json,
225
- :string,
226
- :text,
227
- :time,
228
- :timestamp,
229
- :virtual,
230
- ].each do |column_type|
231
- module_eval <<-CODE, __FILE__, __LINE__ + 1
232
- def #{column_type}(*args, **options)
233
- args.each { |name| column(name, :#{column_type}, options) }
219
+
220
+ included do
221
+ define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
222
+ :float, :integer, :json, :string, :text, :time, :timestamp, :virtual
223
+
224
+ alias :numeric :decimal
225
+ end
226
+
227
+ class_methods do
228
+ private def define_column_methods(*column_types) # :nodoc:
229
+ column_types.each do |column_type|
230
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
231
+ def #{column_type}(*names, **options)
232
+ raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
233
+ names.each { |name| column(name, :#{column_type}, options) }
234
+ end
235
+ RUBY
234
236
  end
235
- CODE
237
+ end
236
238
  end
237
- alias_method :numeric, :decimal
238
239
  end
239
240
 
240
241
  # Represents the schema of an SQL table in an abstract way. This class
@@ -259,10 +260,9 @@ module ActiveRecord
259
260
  include ColumnMethods
260
261
 
261
262
  attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
262
- attr_writer :indexes
263
- deprecate :indexes=
264
263
 
265
264
  def initialize(
265
+ conn,
266
266
  name,
267
267
  temporary: false,
268
268
  if_not_exists: false,
@@ -271,6 +271,7 @@ module ActiveRecord
271
271
  comment: nil,
272
272
  **
273
273
  )
274
+ @conn = conn
274
275
  @columns_hash = {}
275
276
  @indexes = []
276
277
  @foreign_keys = []
@@ -363,7 +364,7 @@ module ActiveRecord
363
364
  # t.references :tagger, polymorphic: true
364
365
  # t.references :taggable, polymorphic: { default: 'Photo' }, index: false
365
366
  # end
366
- def column(name, type, options = {})
367
+ def column(name, type, **options)
367
368
  name = name.to_s
368
369
  type = type.to_sym if type
369
370
  options = options.dup
@@ -397,10 +398,7 @@ module ActiveRecord
397
398
  end
398
399
 
399
400
  def foreign_key(table_name, options = {}) # :nodoc:
400
- table_name_prefix = ActiveRecord::Base.table_name_prefix
401
- table_name_suffix = ActiveRecord::Base.table_name_suffix
402
- table_name = "#{table_name_prefix}#{table_name}#{table_name_suffix}"
403
- foreign_keys.push([table_name, options])
401
+ foreign_keys << [table_name, options]
404
402
  end
405
403
 
406
404
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
@@ -410,6 +408,10 @@ module ActiveRecord
410
408
  def timestamps(**options)
411
409
  options[:null] = false if options[:null].nil?
412
410
 
411
+ if !options.key?(:precision) && @conn.supports_datetime_with_precision?
412
+ options[:precision] = 6
413
+ end
414
+
413
415
  column(:created_at, :datetime, options)
414
416
  column(:updated_at, :datetime, options)
415
417
  end
@@ -517,6 +519,7 @@ module ActiveRecord
517
519
  # t.json
518
520
  # t.virtual
519
521
  # t.remove
522
+ # t.remove_foreign_key
520
523
  # t.remove_references
521
524
  # t.remove_belongs_to
522
525
  # t.remove_index
@@ -538,7 +541,7 @@ module ActiveRecord
538
541
  # t.column(:name, :string)
539
542
  #
540
543
  # See TableDefinition#column for details of the options you can use.
541
- def column(column_name, type, options = {})
544
+ def column(column_name, type, **options)
542
545
  index_options = options.delete(:index)
543
546
  @base.add_column(name, column_name, type, options)
544
547
  index(column_name, index_options.is_a?(Hash) ? index_options : {}) if index_options
@@ -680,15 +683,26 @@ module ActiveRecord
680
683
  end
681
684
  alias :remove_belongs_to :remove_references
682
685
 
683
- # Adds a foreign key.
686
+ # Adds a foreign key to the table using a supplied table name.
684
687
  #
685
688
  # t.foreign_key(:authors)
689
+ # t.foreign_key(:authors, column: :author_id, primary_key: "id")
686
690
  #
687
691
  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
688
692
  def foreign_key(*args)
689
693
  @base.add_foreign_key(name, *args)
690
694
  end
691
695
 
696
+ # Removes the given foreign key from the table.
697
+ #
698
+ # t.remove_foreign_key(:authors)
699
+ # t.remove_foreign_key(column: :author_id)
700
+ #
701
+ # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
702
+ def remove_foreign_key(*args)
703
+ @base.remove_foreign_key(name, *args)
704
+ end
705
+
692
706
  # Checks to see if a foreign key exists.
693
707
  #
694
708
  # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
@@ -130,11 +130,11 @@ module ActiveRecord
130
130
  # column_exists?(:suppliers, :name, :string, null: false)
131
131
  # column_exists?(:suppliers, :tax, :decimal, precision: 8, scale: 2)
132
132
  #
133
- def column_exists?(table_name, column_name, type = nil, options = {})
133
+ def column_exists?(table_name, column_name, type = nil, **options)
134
134
  column_name = column_name.to_s
135
135
  checks = []
136
136
  checks << lambda { |c| c.name == column_name }
137
- checks << lambda { |c| c.type == type } if type
137
+ checks << lambda { |c| c.type == type.to_sym rescue nil } if type
138
138
  column_options_keys.each do |attr|
139
139
  checks << lambda { |c| c.send(attr) == options[attr] } if options.key?(attr)
140
140
  end
@@ -584,7 +584,7 @@ module ActiveRecord
584
584
  # # Defines a column with a database-specific type.
585
585
  # add_column(:shapes, :triangle, 'polygon')
586
586
  # # ALTER TABLE "shapes" ADD "triangle" polygon
587
- def add_column(table_name, column_name, type, options = {})
587
+ def add_column(table_name, column_name, type, **options)
588
588
  at = create_alter_table table_name
589
589
  at.add_column(column_name, type, options)
590
590
  execute schema_creation.accept at
@@ -852,7 +852,7 @@ module ActiveRecord
852
852
  # [<tt>:null</tt>]
853
853
  # Whether the column allows nulls. Defaults to true.
854
854
  #
855
- # ====== Create a user_id bigint column without a index
855
+ # ====== Create a user_id bigint column without an index
856
856
  #
857
857
  # add_reference(:products, :user, index: false)
858
858
  #
@@ -1029,9 +1029,7 @@ module ActiveRecord
1029
1029
  end
1030
1030
 
1031
1031
  def foreign_key_column_for(table_name) # :nodoc:
1032
- prefix = Base.table_name_prefix
1033
- suffix = Base.table_name_suffix
1034
- name = table_name.to_s =~ /#{prefix}(.+)#{suffix}/ ? $1 : table_name.to_s
1032
+ name = strip_table_name_prefix_and_suffix(table_name)
1035
1033
  "#{name.singularize}_id"
1036
1034
  end
1037
1035
 
@@ -1129,6 +1127,10 @@ module ActiveRecord
1129
1127
  def add_timestamps(table_name, options = {})
1130
1128
  options[:null] = false if options[:null].nil?
1131
1129
 
1130
+ if !options.key?(:precision) && supports_datetime_with_precision?
1131
+ options[:precision] = 6
1132
+ end
1133
+
1132
1134
  add_column table_name, :created_at, :datetime, options
1133
1135
  add_column table_name, :updated_at, :datetime, options
1134
1136
  end
@@ -1290,7 +1292,7 @@ module ActiveRecord
1290
1292
  end
1291
1293
 
1292
1294
  def create_table_definition(*args)
1293
- TableDefinition.new(*args)
1295
+ TableDefinition.new(self, *args)
1294
1296
  end
1295
1297
 
1296
1298
  def create_alter_table(name)
@@ -1324,6 +1326,12 @@ module ActiveRecord
1324
1326
  { column: column_names }
1325
1327
  end
1326
1328
 
1329
+ def strip_table_name_prefix_and_suffix(table_name)
1330
+ prefix = Base.table_name_prefix
1331
+ suffix = Base.table_name_suffix
1332
+ table_name.to_s =~ /#{prefix}(.+)#{suffix}/ ? $1 : table_name.to_s
1333
+ end
1334
+
1327
1335
  def foreign_key_name(table_name, options)
1328
1336
  options.fetch(:name) do
1329
1337
  identifier = "#{table_name}_#{options.fetch(:column)}_fk"
@@ -205,9 +205,12 @@ module ActiveRecord
205
205
  run_commit_callbacks: run_commit_callbacks)
206
206
  end
207
207
 
208
- transaction.materialize! unless @connection.supports_lazy_transactions? && lazy_transactions_enabled?
208
+ if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && options[:_lazy] != false
209
+ @has_unmaterialized_transactions = true
210
+ else
211
+ transaction.materialize!
212
+ end
209
213
  @stack.push(transaction)
210
- @has_unmaterialized_transactions = true if @connection.supports_lazy_transactions?
211
214
  transaction
212
215
  end
213
216
  end