activerecord 5.0.0.beta1.1 → 5.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +123 -15
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +1 -1
  5. data/lib/active_record.rb +2 -1
  6. data/lib/active_record/aggregations.rb +1 -1
  7. data/lib/active_record/associations.rb +3 -0
  8. data/lib/active_record/associations/builder/belongs_to.rb +1 -1
  9. data/lib/active_record/associations/builder/has_one.rb +1 -1
  10. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  11. data/lib/active_record/associations/has_many_through_association.rb +5 -0
  12. data/lib/active_record/associations/join_dependency/join_association.rb +1 -2
  13. data/lib/active_record/associations/preloader/through_association.rb +7 -2
  14. data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -7
  15. data/lib/active_record/autosave_association.rb +18 -3
  16. data/lib/active_record/base.rb +0 -3
  17. data/lib/active_record/collection_cache_key.rb +12 -3
  18. data/lib/active_record/connection_adapters/abstract/database_statements.rb +21 -34
  19. data/lib/active_record/connection_adapters/abstract/quoting.rb +8 -4
  20. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
  21. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +7 -1
  22. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +36 -20
  23. data/lib/active_record/connection_adapters/abstract/transaction.rb +8 -2
  24. data/lib/active_record/connection_adapters/abstract_adapter.rb +8 -15
  25. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +57 -198
  26. data/lib/active_record/connection_adapters/column.rb +1 -1
  27. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  28. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  29. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +24 -0
  30. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  31. data/lib/active_record/connection_adapters/mysql2_adapter.rb +15 -34
  32. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +7 -69
  33. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  34. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +4 -0
  35. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -2
  36. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -1
  37. data/lib/active_record/connection_adapters/postgresql/quoting.rb +5 -4
  38. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -7
  39. data/lib/active_record/connection_adapters/postgresql_adapter.rb +15 -23
  40. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  41. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -31
  42. data/lib/active_record/connection_handling.rb +1 -1
  43. data/lib/active_record/core.rb +1 -1
  44. data/lib/active_record/counter_cache.rb +4 -4
  45. data/lib/active_record/enum.rb +8 -5
  46. data/lib/active_record/errors.rb +6 -1
  47. data/lib/active_record/gem_version.rb +1 -1
  48. data/lib/active_record/inheritance.rb +6 -1
  49. data/lib/active_record/internal_metadata.rb +56 -0
  50. data/lib/active_record/migration.rb +85 -20
  51. data/lib/active_record/migration/compatibility.rb +28 -2
  52. data/lib/active_record/model_schema.rb +25 -1
  53. data/lib/active_record/persistence.rb +11 -10
  54. data/lib/active_record/railtie.rb +6 -3
  55. data/lib/active_record/railties/databases.rake +20 -6
  56. data/lib/active_record/reflection.rb +39 -31
  57. data/lib/active_record/relation.rb +4 -4
  58. data/lib/active_record/relation/batches.rb +26 -41
  59. data/lib/active_record/relation/batches/batch_enumerator.rb +6 -6
  60. data/lib/active_record/relation/finder_methods.rb +35 -13
  61. data/lib/active_record/relation/from_clause.rb +1 -1
  62. data/lib/active_record/relation/merger.rb +3 -0
  63. data/lib/active_record/relation/predicate_builder.rb +19 -1
  64. data/lib/active_record/relation/predicate_builder/range_handler.rb +17 -1
  65. data/lib/active_record/relation/query_methods.rb +37 -19
  66. data/lib/active_record/relation/record_fetch_warning.rb +4 -6
  67. data/lib/active_record/relation/where_clause.rb +1 -1
  68. data/lib/active_record/relation/where_clause_factory.rb +1 -0
  69. data/lib/active_record/sanitization.rb +1 -1
  70. data/lib/active_record/schema.rb +3 -0
  71. data/lib/active_record/schema_dumper.rb +1 -1
  72. data/lib/active_record/schema_migration.rb +5 -14
  73. data/lib/active_record/scoping.rb +17 -11
  74. data/lib/active_record/scoping/default.rb +2 -2
  75. data/lib/active_record/tasks/database_tasks.rb +18 -0
  76. data/lib/active_record/timestamp.rb +5 -1
  77. data/lib/active_record/transactions.rb +3 -3
  78. data/lib/active_record/validations/uniqueness.rb +6 -3
  79. data/lib/rails/generators/active_record/migration/templates/migration.rb +4 -0
  80. data/lib/rails/generators/active_record/model/model_generator.rb +7 -1
  81. metadata +14 -7
@@ -5,6 +5,12 @@ module ActiveRecord
5
5
 
6
6
  module FourTwoShared
7
7
  module TableDefinition
8
+ def references(*, **options)
9
+ options[:index] ||= false
10
+ super
11
+ end
12
+ alias :belongs_to :references
13
+
8
14
  def timestamps(*, **options)
9
15
  options[:null] = true if options[:null].nil?
10
16
  super
@@ -24,6 +30,25 @@ module ActiveRecord
24
30
  end
25
31
  end
26
32
 
33
+ def change_table(table_name, options = {})
34
+ if block_given?
35
+ super(table_name, options) do |t|
36
+ class << t
37
+ prepend TableDefinition
38
+ end
39
+ yield t
40
+ end
41
+ else
42
+ super
43
+ end
44
+ end
45
+
46
+ def add_reference(*, **options)
47
+ options[:index] ||= false
48
+ super
49
+ end
50
+ alias :add_belongs_to :add_reference
51
+
27
52
  def add_timestamps(*, **options)
28
53
  options[:null] = true if options[:null].nil?
29
54
  super
@@ -41,8 +66,9 @@ module ActiveRecord
41
66
  end
42
67
 
43
68
  def remove_index(table_name, options = {})
44
- index_name = index_name_for_remove(table_name, options)
45
- execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
69
+ options = { column: options } unless options.is_a?(Hash)
70
+ options[:name] = index_name_for_remove(table_name, options)
71
+ super(table_name, options)
46
72
  end
47
73
 
48
74
  private
@@ -42,6 +42,19 @@ module ActiveRecord
42
42
  class_attribute :schema_migrations_table_name, instance_accessor: false
43
43
  self.schema_migrations_table_name = "schema_migrations"
44
44
 
45
+ ##
46
+ # :singleton-method:
47
+ # Accessor for the name of the internal metadata table. By default, the value is "ar_internal_metadata"
48
+ class_attribute :internal_metadata_table_name, instance_accessor: false
49
+ self.internal_metadata_table_name = "ar_internal_metadata"
50
+
51
+ ##
52
+ # :singleton-method:
53
+ # Accessor for an array of names of environments where destructive actions should be prohibited. By default,
54
+ # the value is ["production"]
55
+ class_attribute :protected_environments, instance_accessor: false
56
+ self.protected_environments = ["production"]
57
+
45
58
  ##
46
59
  # :singleton-method:
47
60
  # Indicates whether table names should be the pluralized versions of the corresponding class names.
@@ -242,7 +255,18 @@ module ActiveRecord
242
255
  @attribute_types ||= Hash.new(Type::Value.new)
243
256
  end
244
257
 
245
- def type_for_attribute(attr_name) # :nodoc:
258
+ # Returns the type of the attribute with the given name, after applying
259
+ # all modifiers. This method is the only valid source of information for
260
+ # anything related to the types of a model's attributes. This method will
261
+ # access the database and load the model's schema if it is required.
262
+ #
263
+ # The return value of this method will implement the interface described
264
+ # by ActiveModel::Type::Value (though the object itself may not subclass
265
+ # it).
266
+ #
267
+ # +attr_name+ The name of the attribute to retrieve the type for. Must be
268
+ # a string
269
+ def type_for_attribute(attr_name)
246
270
  attribute_types[attr_name]
247
271
  end
248
272
 
@@ -102,11 +102,11 @@ module ActiveRecord
102
102
 
103
103
  # Saves the model.
104
104
  #
105
- # If the model is new a record gets created in the database, otherwise
105
+ # If the model is new, a record gets created in the database, otherwise
106
106
  # the existing record gets updated.
107
107
  #
108
- # By default, save always run validations. If any of them fail the action
109
- # is cancelled and #save returns +false+. However, if you supply
108
+ # By default, save always runs validations. If any of them fail the action
109
+ # is cancelled and #save returns +false+, and the record won't be saved. However, if you supply
110
110
  # validate: false, validations are bypassed altogether. See
111
111
  # ActiveRecord::Validations for more information.
112
112
  #
@@ -132,9 +132,10 @@ module ActiveRecord
132
132
  # If the model is new, a record gets created in the database, otherwise
133
133
  # the existing record gets updated.
134
134
  #
135
- # With #save! validations always run. If any of them fail
136
- # ActiveRecord::RecordInvalid gets raised. See ActiveRecord::Validations
137
- # for more information.
135
+ # By default, #save! always runs validations. If any of them fail
136
+ # ActiveRecord::RecordInvalid gets raised, and the record won't be saved. However, if you supply
137
+ # validate: false, validations are bypassed altogether. See
138
+ # ActiveRecord::Validations for more information.
138
139
  #
139
140
  # By default, #save! also sets the +updated_at+/+updated_on+ attributes to
140
141
  # the current time. However, if you supply <tt>touch: false</tt>, these
@@ -246,7 +247,7 @@ module ActiveRecord
246
247
  # This method raises an ActiveRecord::ActiveRecordError if the
247
248
  # attribute is marked as readonly.
248
249
  #
249
- # See also #update_column.
250
+ # Also see #update_column.
250
251
  def update_attribute(name, value)
251
252
  name = name.to_s
252
253
  verify_readonly_attribute(name)
@@ -269,7 +270,7 @@ module ActiveRecord
269
270
  alias update_attributes update
270
271
 
271
272
  # Updates its receiver just like #update but calls #save! instead
272
- # of +save+, so an exception is raised if the record is invalid.
273
+ # of +save+, so an exception is raised if the record is invalid and saving will fail.
273
274
  def update!(attributes)
274
275
  # The following transaction covers any possible database side-effects of the
275
276
  # attributes assignment. For example, setting the IDs of a child collection.
@@ -348,7 +349,7 @@ module ActiveRecord
348
349
  end
349
350
 
350
351
  # Wrapper around #decrement that saves the record. This method differs from
351
- # its non-bang version in that it passes through the attribute setter.
352
+ # its non-bang version in the sense that it passes through the attribute setter.
352
353
  # Saving is not subjected to validation checks. Returns +true+ if the
353
354
  # record could be saved.
354
355
  def decrement!(attribute, by = 1)
@@ -373,7 +374,7 @@ module ActiveRecord
373
374
  end
374
375
 
375
376
  # Wrapper around #toggle that saves the record. This method differs from
376
- # its non-bang version in that it passes through the attribute setter.
377
+ # its non-bang version in the sense that it passes through the attribute setter.
377
378
  # Saving is not subjected to validation checks. Returns +true+ if the
378
379
  # record could be saved.
379
380
  def toggle!(attribute)
@@ -40,7 +40,7 @@ module ActiveRecord
40
40
  task :load_config do
41
41
  ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
42
42
 
43
- if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
43
+ if defined?(ENGINE_ROOT) && engine = Rails::Engine.find(ENGINE_ROOT)
44
44
  if engine.paths['db/migrate'].existent
45
45
  ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths['db/migrate'].to_a
46
46
  end
@@ -57,8 +57,10 @@ module ActiveRecord
57
57
  console do |app|
58
58
  require "active_record/railties/console_sandbox" if app.sandbox?
59
59
  require "active_record/base"
60
- console = ActiveSupport::Logger.new(STDERR)
61
- Rails.logger.extend ActiveSupport::Logger.broadcast console
60
+ unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
61
+ console = ActiveSupport::Logger.new(STDERR)
62
+ Rails.logger.extend ActiveSupport::Logger.broadcast console
63
+ end
62
64
  end
63
65
 
64
66
  runner do
@@ -69,6 +71,7 @@ module ActiveRecord
69
71
  ActiveSupport.on_load(:active_record) do
70
72
  self.time_zone_aware_attributes = true
71
73
  self.default_timezone = :utc
74
+ self.time_zone_aware_types = ActiveRecord::Base.time_zone_aware_types
72
75
  end
73
76
  end
74
77
 
@@ -1,6 +1,16 @@
1
1
  require 'active_record'
2
2
 
3
3
  db_namespace = namespace :db do
4
+ desc "Set the environment value for the database"
5
+ task "environment:set" => [:environment, :load_config] do
6
+ ActiveRecord::InternalMetadata.create_table
7
+ ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
8
+ end
9
+
10
+ task :check_protected_environments => [:environment, :load_config] do
11
+ ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!
12
+ end
13
+
4
14
  task :load_config do
5
15
  ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
6
16
  ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
@@ -18,24 +28,28 @@ db_namespace = namespace :db do
18
28
  end
19
29
 
20
30
  namespace :drop do
21
- task :all => :load_config do
31
+ task :all => [:load_config, :check_protected_environments] do
22
32
  ActiveRecord::Tasks::DatabaseTasks.drop_all
23
33
  end
24
34
  end
25
35
 
26
36
  desc 'Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV, it defaults to dropping the development and test databases.'
27
- task :drop => [:load_config] do
37
+ task :drop => [:load_config, :check_protected_environments] do
38
+ db_namespace["drop:_unsafe"].invoke
39
+ end
40
+
41
+ task "drop:_unsafe" => [:load_config] do
28
42
  ActiveRecord::Tasks::DatabaseTasks.drop_current
29
43
  end
30
44
 
31
45
  namespace :purge do
32
- task :all => :load_config do
46
+ task :all => [:load_config, :check_protected_environments] do
33
47
  ActiveRecord::Tasks::DatabaseTasks.purge_all
34
48
  end
35
49
  end
36
50
 
37
51
  # desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:purge:all to purge all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases."
38
- task :purge => [:load_config] do
52
+ task :purge => [:load_config, :check_protected_environments] do
39
53
  ActiveRecord::Tasks::DatabaseTasks.purge_current
40
54
  end
41
55
 
@@ -288,7 +302,7 @@ db_namespace = namespace :db do
288
302
  end
289
303
 
290
304
  desc "Recreates the databases from the structure.sql file"
291
- task :load => [:load_config] do
305
+ task :load => [:environment, :load_config] do
292
306
  ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:sql, ENV['SCHEMA'])
293
307
  end
294
308
 
@@ -351,7 +365,7 @@ db_namespace = namespace :db do
351
365
  task :clone_structure => %w(db:test:deprecated db:structure:dump db:test:load_structure)
352
366
 
353
367
  # desc "Empty the test database"
354
- task :purge => %w(environment load_config) do
368
+ task :purge => %w(environment load_config check_protected_environments) do
355
369
  ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
356
370
  end
357
371
 
@@ -483,28 +483,7 @@ module ActiveRecord
483
483
  # Returns +true+ if +self+ is a +has_one+ reflection.
484
484
  def has_one?; false; end
485
485
 
486
- def association_class
487
- case macro
488
- when :belongs_to
489
- if polymorphic?
490
- Associations::BelongsToPolymorphicAssociation
491
- else
492
- Associations::BelongsToAssociation
493
- end
494
- when :has_many
495
- if options[:through]
496
- Associations::HasManyThroughAssociation
497
- else
498
- Associations::HasManyAssociation
499
- end
500
- when :has_one
501
- if options[:through]
502
- Associations::HasOneThroughAssociation
503
- else
504
- Associations::HasOneAssociation
505
- end
506
- end
507
- end
486
+ def association_class; raise NotImplementedError; end
508
487
 
509
488
  def polymorphic?
510
489
  options[:polymorphic]
@@ -522,14 +501,7 @@ module ActiveRecord
522
501
  private
523
502
 
524
503
  def calculate_constructable(macro, options)
525
- case macro
526
- when :belongs_to
527
- !polymorphic?
528
- when :has_one
529
- !options[:through]
530
- else
531
- true
532
- end
504
+ true
533
505
  end
534
506
 
535
507
  # Attempts to find the inverse association name automatically.
@@ -545,7 +517,7 @@ module ActiveRecord
545
517
  end
546
518
  end
547
519
 
548
- # returns either nil or the inverse association name that it finds.
520
+ # returns either false or the inverse association name that it finds.
549
521
  def automatic_inverse_of
550
522
  if can_find_inverse_of_automatically?(self)
551
523
  inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym
@@ -629,6 +601,14 @@ module ActiveRecord
629
601
  def macro; :has_many; end
630
602
 
631
603
  def collection?; true; end
604
+
605
+ def association_class
606
+ if options[:through]
607
+ Associations::HasManyThroughAssociation
608
+ else
609
+ Associations::HasManyAssociation
610
+ end
611
+ end
632
612
  end
633
613
 
634
614
  class HasOneReflection < AssociationReflection # :nodoc:
@@ -639,6 +619,20 @@ module ActiveRecord
639
619
  def macro; :has_one; end
640
620
 
641
621
  def has_one?; true; end
622
+
623
+ def association_class
624
+ if options[:through]
625
+ Associations::HasOneThroughAssociation
626
+ else
627
+ Associations::HasOneAssociation
628
+ end
629
+ end
630
+
631
+ private
632
+
633
+ def calculate_constructable(macro, options)
634
+ !options[:through]
635
+ end
642
636
  end
643
637
 
644
638
  class BelongsToReflection < AssociationReflection # :nodoc:
@@ -650,6 +644,14 @@ module ActiveRecord
650
644
 
651
645
  def belongs_to?; true; end
652
646
 
647
+ def association_class
648
+ if polymorphic?
649
+ Associations::BelongsToPolymorphicAssociation
650
+ else
651
+ Associations::BelongsToAssociation
652
+ end
653
+ end
654
+
653
655
  def join_keys(association_klass)
654
656
  key = polymorphic? ? association_primary_key(association_klass) : association_primary_key
655
657
  JoinKeys.new(key, foreign_key)
@@ -658,6 +660,12 @@ module ActiveRecord
658
660
  def join_id_for(owner) # :nodoc:
659
661
  owner[foreign_key]
660
662
  end
663
+
664
+ private
665
+
666
+ def calculate_constructable(macro, options)
667
+ !polymorphic?
668
+ end
661
669
  end
662
670
 
663
671
  class HasAndBelongsToManyReflection < AssociationReflection # :nodoc:
@@ -99,7 +99,7 @@ module ActiveRecord
99
99
  end
100
100
 
101
101
  substitutes = values.map do |(arel_attr, _)|
102
- [arel_attr, connection.substitute_at(klass.columns_hash[arel_attr.name])]
102
+ [arel_attr, Arel::Nodes::BindParam.new]
103
103
  end
104
104
 
105
105
  [substitutes, binds]
@@ -132,7 +132,7 @@ module ActiveRecord
132
132
  # ==== Examples
133
133
  #
134
134
  # users = User.where(name: 'Oscar')
135
- # users.create # => #<User id: 3, name: "oscar", ...>
135
+ # users.create # => #<User id: 3, name: "Oscar", ...>
136
136
  #
137
137
  # users.create(name: 'fxn')
138
138
  # users.create # => #<User id: 4, name: "fxn", ...>
@@ -371,11 +371,11 @@ module ActiveRecord
371
371
 
372
372
  stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates))
373
373
  stmt.table(table)
374
- stmt.key = table[primary_key]
375
374
 
376
375
  if joins_values.any?
377
- @klass.connection.join_to_update(stmt, arel)
376
+ @klass.connection.join_to_update(stmt, arel, table[primary_key])
378
377
  else
378
+ stmt.key = table[primary_key]
379
379
  stmt.take(arel.limit)
380
380
  stmt.order(*arel.orders)
381
381
  stmt.wheres = arel.constraints
@@ -29,15 +29,15 @@ module ActiveRecord
29
29
  #
30
30
  # ==== Options
31
31
  # * <tt>:batch_size</tt> - Specifies the size of the batch. Default to 1000.
32
- # * <tt>:begin_at</tt> - Specifies the primary key value to start from, inclusive of the value.
33
- # * <tt>:end_at</tt> - Specifies the primary key value to end at, inclusive of the value.
32
+ # * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
33
+ # * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
34
34
  # This is especially useful if you want multiple workers dealing with
35
35
  # the same processing queue. You can make worker 1 handle all the records
36
36
  # between id 0 and 10,000 and worker 2 handle from 10,000 and beyond
37
- # (by setting the +:begin_at+ and +:end_at+ option on each worker).
37
+ # (by setting the +:start+ and +:finish+ option on each worker).
38
38
  #
39
39
  # # Let's process for a batch of 2000 records, skipping the first 2000 rows
40
- # Person.find_each(begin_at: 2000, batch_size: 2000) do |person|
40
+ # Person.find_each(start: 2000, batch_size: 2000) do |person|
41
41
  # person.party_all_night!
42
42
  # end
43
43
  #
@@ -48,22 +48,15 @@ module ActiveRecord
48
48
  #
49
49
  # NOTE: You can't set the limit either, that's used to control
50
50
  # the batch sizes.
51
- def find_each(begin_at: nil, end_at: nil, batch_size: 1000, start: nil)
52
- if start
53
- begin_at = start
54
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
55
- Passing `start` value to find_each is deprecated, and will be removed in Rails 5.1.
56
- Please pass `begin_at` instead.
57
- MSG
58
- end
51
+ def find_each(start: nil, finish: nil, batch_size: 1000)
59
52
  if block_given?
60
- find_in_batches(begin_at: begin_at, end_at: end_at, batch_size: batch_size) do |records|
53
+ find_in_batches(start: start, finish: finish, batch_size: batch_size) do |records|
61
54
  records.each { |record| yield record }
62
55
  end
63
56
  else
64
- enum_for(:find_each, begin_at: begin_at, end_at: end_at, batch_size: batch_size) do
57
+ enum_for(:find_each, start: start, finish: finish, batch_size: batch_size) do
65
58
  relation = self
66
- apply_limits(relation, begin_at, end_at).size
59
+ apply_limits(relation, start, finish).size
67
60
  end
68
61
  end
69
62
  end
@@ -88,15 +81,15 @@ module ActiveRecord
88
81
  #
89
82
  # ==== Options
90
83
  # * <tt>:batch_size</tt> - Specifies the size of the batch. Default to 1000.
91
- # * <tt>:begin_at</tt> - Specifies the primary key value to start from, inclusive of the value.
92
- # * <tt>:end_at</tt> - Specifies the primary key value to end at, inclusive of the value.
84
+ # * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
85
+ # * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
93
86
  # This is especially useful if you want multiple workers dealing with
94
87
  # the same processing queue. You can make worker 1 handle all the records
95
88
  # between id 0 and 10,000 and worker 2 handle from 10,000 and beyond
96
- # (by setting the +:begin_at+ and +:end_at+ option on each worker).
89
+ # (by setting the +:start+ and +:finish+ option on each worker).
97
90
  #
98
91
  # # Let's process the next 2000 records
99
- # Person.find_in_batches(begin_at: 2000, batch_size: 2000) do |group|
92
+ # Person.find_in_batches(start: 2000, batch_size: 2000) do |group|
100
93
  # group.each { |person| person.party_all_night! }
101
94
  # end
102
95
  #
@@ -107,24 +100,16 @@ module ActiveRecord
107
100
  #
108
101
  # NOTE: You can't set the limit either, that's used to control
109
102
  # the batch sizes.
110
- def find_in_batches(begin_at: nil, end_at: nil, batch_size: 1000, start: nil)
111
- if start
112
- begin_at = start
113
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
114
- Passing `start` value to find_in_batches is deprecated, and will be removed in Rails 5.1.
115
- Please pass `begin_at` instead.
116
- MSG
117
- end
118
-
103
+ def find_in_batches(start: nil, finish: nil, batch_size: 1000)
119
104
  relation = self
120
105
  unless block_given?
121
- return to_enum(:find_in_batches, begin_at: begin_at, end_at: end_at, batch_size: batch_size) do
122
- total = apply_limits(relation, begin_at, end_at).size
106
+ return to_enum(:find_in_batches, start: start, finish: finish, batch_size: batch_size) do
107
+ total = apply_limits(relation, start, finish).size
123
108
  (total - 1).div(batch_size) + 1
124
109
  end
125
110
  end
126
111
 
127
- in_batches(of: batch_size, begin_at: begin_at, end_at: end_at, load: true) do |batch|
112
+ in_batches(of: batch_size, start: start, finish: finish, load: true) do |batch|
128
113
  yield batch.to_a
129
114
  end
130
115
  end
@@ -153,18 +138,18 @@ module ActiveRecord
153
138
  # ==== Options
154
139
  # * <tt>:of</tt> - Specifies the size of the batch. Default to 1000.
155
140
  # * <tt>:load</tt> - Specifies if the relation should be loaded. Default to false.
156
- # * <tt>:begin_at</tt> - Specifies the primary key value to start from, inclusive of the value.
157
- # * <tt>:end_at</tt> - Specifies the primary key value to end at, inclusive of the value.
141
+ # * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
142
+ # * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
158
143
  #
159
144
  # This is especially useful if you want to work with the
160
145
  # ActiveRecord::Relation object instead of the array of records, or if
161
146
  # you want multiple workers dealing with the same processing queue. You can
162
147
  # make worker 1 handle all the records between id 0 and 10,000 and worker 2
163
- # handle from 10,000 and beyond (by setting the +:begin_at+ and +:end_at+
148
+ # handle from 10,000 and beyond (by setting the +:start+ and +:finish+
164
149
  # option on each worker).
165
150
  #
166
151
  # # Let's process the next 2000 records
167
- # Person.in_batches(of: 2000, begin_at: 2000).update_all(awesome: true)
152
+ # Person.in_batches(of: 2000, start: 2000).update_all(awesome: true)
168
153
  #
169
154
  # An example of calling where query method on the relation:
170
155
  #
@@ -186,10 +171,10 @@ module ActiveRecord
186
171
  #
187
172
  # NOTE: You can't set the limit either, that's used to control the batch
188
173
  # sizes.
189
- def in_batches(of: 1000, begin_at: nil, end_at: nil, load: false)
174
+ def in_batches(of: 1000, start: nil, finish: nil, load: false)
190
175
  relation = self
191
176
  unless block_given?
192
- return BatchEnumerator.new(of: of, begin_at: begin_at, end_at: end_at, relation: self)
177
+ return BatchEnumerator.new(of: of, start: start, finish: finish, relation: self)
193
178
  end
194
179
 
195
180
  if logger && (arel.orders.present? || arel.taken.present?)
@@ -197,7 +182,7 @@ module ActiveRecord
197
182
  end
198
183
 
199
184
  relation = relation.reorder(batch_order).limit(of)
200
- relation = apply_limits(relation, begin_at, end_at)
185
+ relation = apply_limits(relation, start, finish)
201
186
  batch_relation = relation
202
187
 
203
188
  loop do
@@ -225,9 +210,9 @@ module ActiveRecord
225
210
 
226
211
  private
227
212
 
228
- def apply_limits(relation, begin_at, end_at)
229
- relation = relation.where(table[primary_key].gteq(begin_at)) if begin_at
230
- relation = relation.where(table[primary_key].lteq(end_at)) if end_at
213
+ def apply_limits(relation, start, finish)
214
+ relation = relation.where(table[primary_key].gteq(start)) if start
215
+ relation = relation.where(table[primary_key].lteq(finish)) if finish
231
216
  relation
232
217
  end
233
218