activerecord 6.0.0.rc1 → 6.0.0.rc2

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/lib/active_record/associations/builder/collection_association.rb +2 -2
  4. data/lib/active_record/associations/collection_proxy.rb +1 -1
  5. data/lib/active_record/associations/join_dependency.rb +10 -9
  6. data/lib/active_record/associations/join_dependency/join_association.rb +11 -2
  7. data/lib/active_record/associations/preloader/association.rb +3 -1
  8. data/lib/active_record/attribute_methods.rb +0 -51
  9. data/lib/active_record/attribute_methods/dirty.rb +6 -1
  10. data/lib/active_record/autosave_association.rb +1 -1
  11. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +93 -11
  12. data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -3
  13. data/lib/active_record/connection_adapters/abstract/quoting.rb +53 -0
  14. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
  15. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -7
  16. data/lib/active_record/connection_adapters/abstract/transaction.rb +12 -4
  17. data/lib/active_record/connection_adapters/abstract_adapter.rb +40 -20
  18. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
  19. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  20. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +3 -1
  21. data/lib/active_record/connection_adapters/mysql2_adapter.rb +10 -1
  22. data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
  23. data/lib/active_record/connection_adapters/postgresql_adapter.rb +8 -1
  24. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -2
  25. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +12 -2
  26. data/lib/active_record/connection_handling.rb +6 -2
  27. data/lib/active_record/database_configurations.rb +6 -6
  28. data/lib/active_record/gem_version.rb +1 -1
  29. data/lib/active_record/middleware/database_selector.rb +3 -3
  30. data/lib/active_record/middleware/database_selector/resolver.rb +2 -2
  31. data/lib/active_record/migration.rb +26 -23
  32. data/lib/active_record/railtie.rb +0 -1
  33. data/lib/active_record/railties/databases.rake +57 -23
  34. data/lib/active_record/reflection.rb +1 -1
  35. data/lib/active_record/relation/calculations.rb +1 -1
  36. data/lib/active_record/relation/finder_methods.rb +4 -2
  37. data/lib/active_record/relation/merger.rb +6 -2
  38. data/lib/active_record/relation/query_methods.rb +32 -32
  39. data/lib/active_record/sanitization.rb +30 -2
  40. data/lib/active_record/schema.rb +1 -1
  41. data/lib/active_record/schema_dumper.rb +5 -1
  42. data/lib/active_record/table_metadata.rb +6 -10
  43. data/lib/active_record/tasks/database_tasks.rb +41 -8
  44. data/lib/active_record/tasks/mysql_database_tasks.rb +3 -1
  45. data/lib/active_record/timestamp.rb +26 -16
  46. data/lib/active_record/touch_later.rb +2 -0
  47. data/lib/active_record/transactions.rb +9 -10
  48. data/lib/active_record/type_caster/connection.rb +16 -10
  49. data/lib/arel/visitors/depth_first.rb +1 -1
  50. data/lib/arel/visitors/to_sql.rb +23 -26
  51. data/lib/arel/visitors/visitor.rb +9 -5
  52. metadata +8 -8
@@ -23,6 +23,7 @@ module ActiveRecord
23
23
 
24
24
  surreptitiously_touch @_defer_touch_attrs
25
25
  add_to_transaction
26
+ @_new_record_before_last_commit ||= false
26
27
 
27
28
  # touch the parents as we are not calling the after_save callbacks
28
29
  self.class.reflect_on_all_associations(:belongs_to).each do |r|
@@ -48,6 +49,7 @@ module ActiveRecord
48
49
 
49
50
  def touch_deferred_attributes
50
51
  if has_defer_touch_attrs? && persisted?
52
+ @_skip_dirty_tracking = true
51
53
  touch(*@_defer_touch_attrs, time: @_touch_time)
52
54
  @_defer_touch_attrs, @_touch_time = nil, nil
53
55
  end
@@ -333,7 +333,7 @@ module ActiveRecord
333
333
  # Ensure that it is not called if the object was never persisted (failed create),
334
334
  # but call it after the commit of a destroyed object.
335
335
  def committed!(should_run_callbacks: true) #:nodoc:
336
- if should_run_callbacks && (destroyed? || persisted?)
336
+ if should_run_callbacks
337
337
  @_committed_already_called = true
338
338
  _run_commit_without_transaction_enrollment_callbacks
339
339
  _run_commit_callbacks
@@ -364,7 +364,9 @@ module ActiveRecord
364
364
  def with_transaction_returning_status
365
365
  status = nil
366
366
  self.class.transaction do
367
- unless has_transactional_callbacks?
367
+ if has_transactional_callbacks?
368
+ add_to_transaction
369
+ else
368
370
  sync_with_transaction_state if @transaction_state&.finalized?
369
371
  @transaction_state = self.class.connection.transaction_state
370
372
  end
@@ -372,15 +374,15 @@ module ActiveRecord
372
374
 
373
375
  status = yield
374
376
  raise ActiveRecord::Rollback unless status
375
- ensure
376
- if has_transactional_callbacks? &&
377
- (@_new_record_before_last_commit && !new_record? || _trigger_update_callback || _trigger_destroy_callback)
378
- add_to_transaction
379
- end
380
377
  end
381
378
  status
382
379
  end
383
380
 
381
+ def trigger_transactional_callbacks? # :nodoc:
382
+ (@_new_record_before_last_commit || _trigger_update_callback) && persisted? ||
383
+ _trigger_destroy_callback && destroyed?
384
+ end
385
+
384
386
  private
385
387
  attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
386
388
 
@@ -395,10 +397,7 @@ module ActiveRecord
395
397
  level: 0
396
398
  }
397
399
  @_start_transaction_state[:level] += 1
398
- remember_new_record_before_last_commit
399
- end
400
400
 
401
- def remember_new_record_before_last_commit
402
401
  if _committed_already_called
403
402
  @_new_record_before_last_commit = false
404
403
  else
@@ -8,21 +8,27 @@ module ActiveRecord
8
8
  @table_name = table_name
9
9
  end
10
10
 
11
- def type_cast_for_database(attribute_name, value)
11
+ def type_cast_for_database(attr_name, value)
12
12
  return value if value.is_a?(Arel::Nodes::BindParam)
13
- column = column_for(attribute_name)
14
- connection.type_cast_from_column(column, value)
13
+ type = type_for_attribute(attr_name)
14
+ type.serialize(value)
15
15
  end
16
16
 
17
- private
18
- attr_reader :table_name
19
- delegate :connection, to: :@klass
17
+ def type_for_attribute(attr_name)
18
+ schema_cache = connection.schema_cache
20
19
 
21
- def column_for(attribute_name)
22
- if connection.schema_cache.data_source_exists?(table_name)
23
- connection.schema_cache.columns_hash(table_name)[attribute_name.to_s]
24
- end
20
+ if schema_cache.data_source_exists?(table_name)
21
+ column = schema_cache.columns_hash(table_name)[attr_name.to_s]
22
+ type = connection.lookup_cast_type_from_column(column) if column
25
23
  end
24
+
25
+ type || Type.default_value
26
+ end
27
+
28
+ delegate :connection, to: :@klass, private: true
29
+
30
+ private
31
+ attr_reader :table_name
26
32
  end
27
33
  end
28
34
  end
@@ -10,7 +10,7 @@ module Arel # :nodoc: all
10
10
 
11
11
  private
12
12
 
13
- def visit(o)
13
+ def visit(o, _ = nil)
14
14
  super
15
15
  @block.call o
16
16
  end
@@ -52,10 +52,14 @@ module Arel # :nodoc: all
52
52
  def visit_Arel_Nodes_InsertStatement(o, collector)
53
53
  collector << "INSERT INTO "
54
54
  collector = visit o.relation, collector
55
- if o.columns.any?
56
- collector << " (#{o.columns.map { |x|
57
- quote_column_name x.name
58
- }.join ', '})"
55
+
56
+ unless o.columns.empty?
57
+ collector << " ("
58
+ o.columns.each_with_index do |x, i|
59
+ collector << ", " unless i == 0
60
+ collector << quote_column_name(x.name)
61
+ end
62
+ collector << ")"
59
63
  end
60
64
 
61
65
  if o.values
@@ -97,22 +101,20 @@ module Arel # :nodoc: all
97
101
  def visit_Arel_Nodes_ValuesList(o, collector)
98
102
  collector << "VALUES "
99
103
 
100
- len = o.rows.length - 1
101
- o.rows.each_with_index { |row, i|
104
+ o.rows.each_with_index do |row, i|
105
+ collector << ", " unless i == 0
102
106
  collector << "("
103
- row_len = row.length - 1
104
107
  row.each_with_index do |value, k|
108
+ collector << ", " unless k == 0
105
109
  case value
106
110
  when Nodes::SqlLiteral, Nodes::BindParam
107
111
  collector = visit(value, collector)
108
112
  else
109
113
  collector << quote(value).to_s
110
114
  end
111
- collector << ", " unless k == row_len
112
115
  end
113
116
  collector << ")"
114
- collector << ", " unless i == len
115
- }
117
+ end
116
118
  collector
117
119
  end
118
120
 
@@ -128,11 +130,10 @@ module Arel # :nodoc: all
128
130
 
129
131
  unless o.orders.empty?
130
132
  collector << " ORDER BY "
131
- len = o.orders.length - 1
132
- o.orders.each_with_index { |x, i|
133
+ o.orders.each_with_index do |x, i|
134
+ collector << ", " unless i == 0
133
135
  collector = visit(x, collector)
134
- collector << ", " unless len == i
135
- }
136
+ end
136
137
  end
137
138
 
138
139
  visit_Arel_Nodes_SelectOptions(o, collector)
@@ -506,7 +507,7 @@ module Arel # :nodoc: all
506
507
 
507
508
  def visit_Arel_Table(o, collector)
508
509
  if o.table_alias
509
- collector << "#{quote_table_name o.name} #{quote_table_name o.table_alias}"
510
+ collector << quote_table_name(o.name) << " " << quote_table_name(o.table_alias)
510
511
  else
511
512
  collector << quote_table_name(o.name)
512
513
  end
@@ -682,13 +683,12 @@ module Arel # :nodoc: all
682
683
  end
683
684
 
684
685
  def visit_Arel_Nodes_UnqualifiedColumn(o, collector)
685
- collector << "#{quote_column_name o.name}"
686
- collector
686
+ collector << quote_column_name(o.name)
687
687
  end
688
688
 
689
689
  def visit_Arel_Attributes_Attribute(o, collector)
690
690
  join_name = o.relation.table_alias || o.relation.name
691
- collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
691
+ collector << quote_table_name(join_name) << "." << quote_column_name(o.name)
692
692
  end
693
693
  alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
694
694
  alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
@@ -785,14 +785,11 @@ module Arel # :nodoc: all
785
785
  end
786
786
 
787
787
  def inject_join(list, collector, join_str)
788
- len = list.length - 1
789
- list.each_with_index.inject(collector) { |c, (x, i)|
790
- if i == len
791
- visit x, c
792
- else
793
- visit(x, c) << join_str
794
- end
795
- }
788
+ list.each_with_index do |x, i|
789
+ collector << join_str unless i == 0
790
+ collector = visit(x, collector)
791
+ end
792
+ collector
796
793
  end
797
794
 
798
795
  def unboundable?(value)
@@ -7,8 +7,8 @@ module Arel # :nodoc: all
7
7
  @dispatch = get_dispatch_cache
8
8
  end
9
9
 
10
- def accept(object, *args)
11
- visit object, *args
10
+ def accept(object, collector = nil)
11
+ visit object, collector
12
12
  end
13
13
 
14
14
  private
@@ -16,7 +16,7 @@ module Arel # :nodoc: all
16
16
  attr_reader :dispatch
17
17
 
18
18
  def self.dispatch_cache
19
- Hash.new do |hash, klass|
19
+ @dispatch_cache ||= Hash.new do |hash, klass|
20
20
  hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
21
21
  end
22
22
  end
@@ -25,9 +25,13 @@ module Arel # :nodoc: all
25
25
  self.class.dispatch_cache
26
26
  end
27
27
 
28
- def visit(object, *args)
28
+ def visit(object, collector = nil)
29
29
  dispatch_method = dispatch[object.class]
30
- send dispatch_method, object, *args
30
+ if collector
31
+ send dispatch_method, object, collector
32
+ else
33
+ send dispatch_method, object
34
+ end
31
35
  rescue NoMethodError => e
32
36
  raise e if respond_to?(dispatch_method, true)
33
37
  superklass = object.class.ancestors.find { |klass|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.rc1
4
+ version: 6.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-24 00:00:00.000000000 Z
11
+ date: 2019-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 6.0.0.rc1
19
+ version: 6.0.0.rc2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 6.0.0.rc1
26
+ version: 6.0.0.rc2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 6.0.0.rc1
33
+ version: 6.0.0.rc2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 6.0.0.rc1
40
+ version: 6.0.0.rc2
41
41
  description: Databases on Rails. Build a persistent domain model by mapping database
42
42
  tables to Ruby classes. Strong conventions for associations, validations, aggregations,
43
43
  migrations, and testing come baked-in.
@@ -389,8 +389,8 @@ homepage: https://rubyonrails.org
389
389
  licenses:
390
390
  - MIT
391
391
  metadata:
392
- source_code_uri: https://github.com/rails/rails/tree/v6.0.0.rc1/activerecord
393
- changelog_uri: https://github.com/rails/rails/blob/v6.0.0.rc1/activerecord/CHANGELOG.md
392
+ source_code_uri: https://github.com/rails/rails/tree/v6.0.0.rc2/activerecord
393
+ changelog_uri: https://github.com/rails/rails/blob/v6.0.0.rc2/activerecord/CHANGELOG.md
394
394
  post_install_message:
395
395
  rdoc_options:
396
396
  - "--main"