activerecord 4.0.13 → 4.1.0.beta1

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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +745 -2700
  3. data/README.rdoc +2 -2
  4. data/examples/performance.rb +30 -18
  5. data/examples/simple.rb +4 -4
  6. data/lib/active_record.rb +2 -6
  7. data/lib/active_record/aggregations.rb +2 -1
  8. data/lib/active_record/association_relation.rb +0 -4
  9. data/lib/active_record/associations.rb +87 -43
  10. data/lib/active_record/associations/alias_tracker.rb +1 -3
  11. data/lib/active_record/associations/association.rb +8 -16
  12. data/lib/active_record/associations/association_scope.rb +5 -16
  13. data/lib/active_record/associations/belongs_to_association.rb +34 -25
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  15. data/lib/active_record/associations/builder/association.rb +78 -54
  16. data/lib/active_record/associations/builder/belongs_to.rb +91 -58
  17. data/lib/active_record/associations/builder/collection_association.rb +47 -45
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +107 -25
  19. data/lib/active_record/associations/builder/has_many.rb +2 -2
  20. data/lib/active_record/associations/builder/has_one.rb +5 -7
  21. data/lib/active_record/associations/builder/singular_association.rb +6 -7
  22. data/lib/active_record/associations/collection_association.rb +68 -105
  23. data/lib/active_record/associations/collection_proxy.rb +12 -15
  24. data/lib/active_record/associations/has_many_association.rb +11 -9
  25. data/lib/active_record/associations/has_many_through_association.rb +16 -12
  26. data/lib/active_record/associations/has_one_association.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +204 -165
  28. data/lib/active_record/associations/join_dependency/join_association.rb +43 -101
  29. data/lib/active_record/associations/join_dependency/join_base.rb +6 -8
  30. data/lib/active_record/associations/join_dependency/join_part.rb +18 -37
  31. data/lib/active_record/associations/join_helper.rb +2 -11
  32. data/lib/active_record/associations/preloader.rb +89 -34
  33. data/lib/active_record/associations/preloader/association.rb +43 -25
  34. data/lib/active_record/associations/preloader/collection_association.rb +2 -2
  35. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  36. data/lib/active_record/associations/preloader/singular_association.rb +3 -3
  37. data/lib/active_record/associations/preloader/through_association.rb +58 -26
  38. data/lib/active_record/associations/singular_association.rb +6 -5
  39. data/lib/active_record/associations/through_association.rb +2 -2
  40. data/lib/active_record/attribute_assignment.rb +5 -2
  41. data/lib/active_record/attribute_methods.rb +45 -40
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -1
  43. data/lib/active_record/attribute_methods/dirty.rb +8 -22
  44. data/lib/active_record/attribute_methods/primary_key.rb +1 -7
  45. data/lib/active_record/attribute_methods/read.rb +55 -28
  46. data/lib/active_record/attribute_methods/serialization.rb +12 -33
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -13
  48. data/lib/active_record/attribute_methods/write.rb +37 -12
  49. data/lib/active_record/autosave_association.rb +207 -207
  50. data/lib/active_record/base.rb +5 -1
  51. data/lib/active_record/callbacks.rb +2 -2
  52. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +2 -7
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +11 -22
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +12 -14
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -5
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +84 -0
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -8
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +52 -83
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +0 -5
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +14 -97
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +58 -60
  63. data/lib/active_record/connection_adapters/column.rb +1 -35
  64. data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
  65. data/lib/active_record/connection_adapters/mysql2_adapter.rb +3 -4
  66. data/lib/active_record/connection_adapters/mysql_adapter.rb +16 -15
  67. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +24 -18
  68. data/lib/active_record/connection_adapters/postgresql/cast.rb +20 -16
  69. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +23 -43
  70. data/lib/active_record/connection_adapters/postgresql/oid.rb +19 -12
  71. data/lib/active_record/connection_adapters/postgresql/quoting.rb +28 -23
  72. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +8 -30
  73. data/lib/active_record/connection_adapters/postgresql_adapter.rb +92 -75
  74. data/lib/active_record/connection_adapters/schema_cache.rb +8 -29
  75. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +31 -64
  76. data/lib/active_record/connection_handling.rb +2 -2
  77. data/lib/active_record/core.rb +22 -43
  78. data/lib/active_record/counter_cache.rb +7 -7
  79. data/lib/active_record/enum.rb +100 -0
  80. data/lib/active_record/errors.rb +10 -5
  81. data/lib/active_record/fixture_set/file.rb +2 -1
  82. data/lib/active_record/fixtures.rb +171 -74
  83. data/lib/active_record/inheritance.rb +16 -22
  84. data/lib/active_record/integration.rb +52 -1
  85. data/lib/active_record/locking/optimistic.rb +7 -2
  86. data/lib/active_record/locking/pessimistic.rb +1 -1
  87. data/lib/active_record/log_subscriber.rb +5 -12
  88. data/lib/active_record/migration.rb +62 -46
  89. data/lib/active_record/migration/command_recorder.rb +7 -13
  90. data/lib/active_record/model_schema.rb +7 -14
  91. data/lib/active_record/nested_attributes.rb +10 -8
  92. data/lib/active_record/no_touching.rb +52 -0
  93. data/lib/active_record/null_relation.rb +3 -3
  94. data/lib/active_record/persistence.rb +16 -34
  95. data/lib/active_record/querying.rb +14 -12
  96. data/lib/active_record/railtie.rb +0 -50
  97. data/lib/active_record/railties/databases.rake +12 -15
  98. data/lib/active_record/readonly_attributes.rb +0 -6
  99. data/lib/active_record/reflection.rb +189 -75
  100. data/lib/active_record/relation.rb +69 -94
  101. data/lib/active_record/relation/batches.rb +57 -23
  102. data/lib/active_record/relation/calculations.rb +36 -43
  103. data/lib/active_record/relation/delegation.rb +54 -39
  104. data/lib/active_record/relation/finder_methods.rb +107 -62
  105. data/lib/active_record/relation/merger.rb +7 -20
  106. data/lib/active_record/relation/predicate_builder.rb +57 -38
  107. data/lib/active_record/relation/predicate_builder/array_handler.rb +29 -0
  108. data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
  109. data/lib/active_record/relation/query_methods.rb +110 -98
  110. data/lib/active_record/relation/spawn_methods.rb +1 -2
  111. data/lib/active_record/result.rb +45 -6
  112. data/lib/active_record/runtime_registry.rb +5 -0
  113. data/lib/active_record/sanitization.rb +6 -8
  114. data/lib/active_record/schema_dumper.rb +16 -5
  115. data/lib/active_record/schema_migration.rb +24 -25
  116. data/lib/active_record/scoping/default.rb +5 -18
  117. data/lib/active_record/scoping/named.rb +8 -29
  118. data/lib/active_record/store.rb +56 -28
  119. data/lib/active_record/tasks/database_tasks.rb +8 -4
  120. data/lib/active_record/timestamp.rb +4 -4
  121. data/lib/active_record/transactions.rb +8 -10
  122. data/lib/active_record/validations/presence.rb +1 -1
  123. data/lib/active_record/validations/uniqueness.rb +1 -6
  124. data/lib/active_record/version.rb +1 -1
  125. data/lib/rails/generators/active_record.rb +2 -8
  126. data/lib/rails/generators/active_record/migration.rb +18 -0
  127. data/lib/rails/generators/active_record/migration/migration_generator.rb +4 -0
  128. data/lib/rails/generators/active_record/model/model_generator.rb +4 -0
  129. metadata +32 -45
  130. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -65
  131. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  132. data/lib/active_record/tasks/firebird_database_tasks.rb +0 -56
  133. data/lib/active_record/tasks/oracle_database_tasks.rb +0 -45
  134. data/lib/active_record/tasks/sqlserver_database_tasks.rb +0 -48
  135. data/lib/active_record/test_case.rb +0 -102
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- # Determine whether to store the full constant name including namespace when using STI
8
+ # Determines whether to store the full constant name including namespace when using STI.
9
9
  class_attribute :store_full_sti_class, instance_writer: false
10
10
  self.store_full_sti_class = true
11
11
  end
@@ -13,25 +13,22 @@ module ActiveRecord
13
13
  module ClassMethods
14
14
  # Determines if one of the attributes passed in is the inheritance column,
15
15
  # and if the inheritance column is attr accessible, it initializes an
16
- # instance of the given subclass instead of the base class
16
+ # instance of the given subclass instead of the base class.
17
17
  def new(*args, &block)
18
18
  if abstract_class? || self == Base
19
19
  raise NotImplementedError, "#{self} is an abstract class and can not be instantiated."
20
20
  end
21
-
22
- attrs = args.first
23
- if subclass_from_attributes?(attrs)
24
- subclass = subclass_from_attributes(attrs)
25
- end
26
-
27
- if subclass
28
- subclass.new(*args, &block)
29
- else
30
- super
21
+ if (attrs = args.first).is_a?(Hash)
22
+ if subclass = subclass_from_attrs(attrs)
23
+ return subclass.new(*args, &block)
24
+ end
31
25
  end
26
+ # Delegate to the original .new
27
+ super
32
28
  end
33
29
 
34
- # True if this isn't a concrete subclass needing a STI type condition.
30
+ # Returns +true+ if this does not need STI type condition. Returns
31
+ # +false+ if STI type condition needs to be applied.
35
32
  def descends_from_active_record?
36
33
  if self == Base
37
34
  false
@@ -120,9 +117,10 @@ module ActiveRecord
120
117
  begin
121
118
  constant = ActiveSupport::Dependencies.constantize(candidate)
122
119
  return constant if candidate == constant.to_s
123
- rescue NameError => e
124
- # We don't want to swallow NoMethodError < NameError errors
125
- raise e unless e.instance_of?(NameError)
120
+ # We don't want to swallow NoMethodError < NameError errors
121
+ rescue NoMethodError
122
+ raise
123
+ rescue NameError
126
124
  end
127
125
  end
128
126
 
@@ -162,7 +160,7 @@ module ActiveRecord
162
160
  end
163
161
 
164
162
  def type_condition(table = arel_table)
165
- sti_column = table[inheritance_column.to_sym]
163
+ sti_column = table[inheritance_column]
166
164
  sti_names = ([self] + descendants).map { |model| model.sti_name }
167
165
 
168
166
  sti_column.in(sti_names)
@@ -172,11 +170,7 @@ module ActiveRecord
172
170
  # is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
173
171
  # If this is a StrongParameters hash, and access to inheritance_column is not permitted,
174
172
  # this will ignore the inheritance column and return nil
175
- def subclass_from_attributes?(attrs)
176
- columns_hash.include?(inheritance_column) && attrs.is_a?(Hash)
177
- end
178
-
179
- def subclass_from_attributes(attrs)
173
+ def subclass_from_attrs(attrs)
180
174
  subclass_name = attrs.with_indifferent_access[inheritance_column]
181
175
 
182
176
  if subclass_name.present? && subclass_name != self.name
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/string/filters'
2
+
1
3
  module ActiveRecord
2
4
  module Integration
3
5
  extend ActiveSupport::Concern
@@ -45,10 +47,19 @@ module ActiveRecord
45
47
  # Product.new.cache_key # => "products/new"
46
48
  # Product.find(5).cache_key # => "products/5" (updated_at not available)
47
49
  # Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
48
- def cache_key
50
+ #
51
+ # You can also pass a list of named timestamps, and the newest in the list will be
52
+ # used to generate the key:
53
+ #
54
+ # Person.find(5).cache_key(:updated_at, :last_reviewed_at)
55
+ def cache_key(*timestamp_names)
49
56
  case
50
57
  when new_record?
51
58
  "#{self.class.model_name.cache_key}/new"
59
+ when timestamp_names.any?
60
+ timestamp = max_updated_column_timestamp(timestamp_names)
61
+ timestamp = timestamp.utc.to_s(cache_timestamp_format)
62
+ "#{self.class.model_name.cache_key}/#{id}-#{timestamp}"
52
63
  when timestamp = max_updated_column_timestamp
53
64
  timestamp = timestamp.utc.to_s(cache_timestamp_format)
54
65
  "#{self.class.model_name.cache_key}/#{id}-#{timestamp}"
@@ -56,5 +67,45 @@ module ActiveRecord
56
67
  "#{self.class.model_name.cache_key}/#{id}"
57
68
  end
58
69
  end
70
+
71
+ module ClassMethods
72
+ # Defines your model's +to_param+ method to generate "pretty" URLs
73
+ # using +method_name+, which can be any attribute or method that
74
+ # responds to +to_s+.
75
+ #
76
+ # class User < ActiveRecord::Base
77
+ # to_param :name
78
+ # end
79
+ #
80
+ # user = User.find_by(name: 'Fancy Pants')
81
+ # user.id # => 123
82
+ # user_path(user) # => "/users/123-fancy-pants"
83
+ #
84
+ # Values longer than 20 characters will be truncated. The value
85
+ # is truncated word by word.
86
+ #
87
+ # user = User.find_by(name: 'David HeinemeierHansson')
88
+ # user.id # => 125
89
+ # user_path(user) # => "/users/125-david"
90
+ #
91
+ # Because the generated param begins with the record's +id+, it is
92
+ # suitable for passing to +find+. In a controller, for example:
93
+ #
94
+ # params[:id] # => "123-fancy-pants"
95
+ # User.find(params[:id]).id # => 123
96
+ def to_param(method_name = nil)
97
+ if method_name.nil?
98
+ super()
99
+ else
100
+ define_method :to_param do
101
+ if (default = super()) && (result = send(method_name).to_s).present?
102
+ "#{default}-#{result.squish.truncate(20, separator: /\s/, omission: nil).parameterize}"
103
+ else
104
+ default
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
59
110
  end
60
111
  end
@@ -66,7 +66,7 @@ module ActiveRecord
66
66
  send(lock_col + '=', previous_lock_value + 1)
67
67
  end
68
68
 
69
- def _update_record(attribute_names = @attributes.keys) #:nodoc:
69
+ def update_record(attribute_names = @attributes.keys) #:nodoc:
70
70
  return super unless locking_enabled?
71
71
  return 0 if attribute_names.empty?
72
72
 
@@ -84,7 +84,10 @@ module ActiveRecord
84
84
  relation.table[self.class.primary_key].eq(id).and(
85
85
  relation.table[lock_col].eq(self.class.quote_value(previous_lock_value, column_for_attribute(lock_col)))
86
86
  )
87
- ).arel.compile_update(arel_attributes_with_values_for_update(attribute_names))
87
+ ).arel.compile_update(
88
+ arel_attributes_with_values_for_update(attribute_names),
89
+ self.class.primary_key
90
+ )
88
91
 
89
92
  affected_rows = self.class.connection.update stmt
90
93
 
@@ -138,6 +141,7 @@ module ActiveRecord
138
141
 
139
142
  # Set the column to use for optimistic locking. Defaults to +lock_version+.
140
143
  def locking_column=(value)
144
+ @column_defaults = nil
141
145
  @locking_column = value.to_s
142
146
  end
143
147
 
@@ -149,6 +153,7 @@ module ActiveRecord
149
153
 
150
154
  # Quote the column name used for optimistic locking.
151
155
  def quoted_locking_column
156
+ ActiveSupport::Deprecation.warn "ActiveRecord::Base.quoted_locking_column is deprecated and will be removed in Rails 4.2 or later."
152
157
  connection.quote_column_name(locking_column)
153
158
  end
154
159
 
@@ -64,7 +64,7 @@ module ActiveRecord
64
64
  end
65
65
 
66
66
  # Wraps the passed block in a transaction, locking the object
67
- # before yielding. You pass can the SQL locking clause
67
+ # before yielding. You can pass the SQL locking clause
68
68
  # as argument (see <tt>lock!</tt>).
69
69
  def with_lock(lock = true)
70
70
  transaction do
@@ -17,12 +17,14 @@ module ActiveRecord
17
17
 
18
18
  def initialize
19
19
  super
20
- @odd_or_even = false
20
+ @odd = false
21
21
  end
22
22
 
23
23
  def render_bind(column, value)
24
24
  if column
25
25
  if column.binary?
26
+ # This specifically deals with the PG adapter that casts bytea columns into a Hash.
27
+ value = value[:value] if value.is_a?(Hash)
26
28
  value = "<#{value.bytesize} bytes of binary data>"
27
29
  end
28
30
 
@@ -41,7 +43,7 @@ module ActiveRecord
41
43
  return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
42
44
 
43
45
  name = "#{payload[:name]} (#{event.duration.round(1)}ms)"
44
- sql = payload[:sql].squeeze(' ')
46
+ sql = payload[:sql]
45
47
  binds = nil
46
48
 
47
49
  unless (payload[:binds] || []).empty?
@@ -60,17 +62,8 @@ module ActiveRecord
60
62
  debug " #{name} #{sql}#{binds}"
61
63
  end
62
64
 
63
- def identity(event)
64
- return unless logger.debug?
65
-
66
- name = color(event.payload[:name], odd? ? CYAN : MAGENTA, true)
67
- line = odd? ? color(event.payload[:line], nil, true) : event.payload[:line]
68
-
69
- debug " #{name} #{line}"
70
- end
71
-
72
65
  def odd?
73
- @odd_or_even = !@odd_or_even
66
+ @odd = !@odd
74
67
  end
75
68
 
76
69
  def logger
@@ -1,41 +1,48 @@
1
- require "active_support/core_ext/class/attribute_accessors"
1
+ require "active_support/core_ext/module/attribute_accessors"
2
2
  require 'set'
3
3
 
4
4
  module ActiveRecord
5
+ class MigrationError < ActiveRecordError#:nodoc:
6
+ def initialize(message = nil)
7
+ message = "\n\n#{message}\n\n" if message
8
+ super
9
+ end
10
+ end
11
+
5
12
  # Exception that can be raised to stop migrations from going backwards.
6
- class IrreversibleMigration < ActiveRecordError
13
+ class IrreversibleMigration < MigrationError
7
14
  end
8
15
 
9
- class DuplicateMigrationVersionError < ActiveRecordError#:nodoc:
16
+ class DuplicateMigrationVersionError < MigrationError#:nodoc:
10
17
  def initialize(version)
11
18
  super("Multiple migrations have the version number #{version}")
12
19
  end
13
20
  end
14
21
 
15
- class DuplicateMigrationNameError < ActiveRecordError#:nodoc:
22
+ class DuplicateMigrationNameError < MigrationError#:nodoc:
16
23
  def initialize(name)
17
24
  super("Multiple migrations have the name #{name}")
18
25
  end
19
26
  end
20
27
 
21
- class UnknownMigrationVersionError < ActiveRecordError #:nodoc:
28
+ class UnknownMigrationVersionError < MigrationError #:nodoc:
22
29
  def initialize(version)
23
30
  super("No migration with version number #{version}")
24
31
  end
25
32
  end
26
33
 
27
- class IllegalMigrationNameError < ActiveRecordError#:nodoc:
34
+ class IllegalMigrationNameError < MigrationError#:nodoc:
28
35
  def initialize(name)
29
36
  super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed)")
30
37
  end
31
38
  end
32
39
 
33
- class PendingMigrationError < ActiveRecordError#:nodoc:
40
+ class PendingMigrationError < MigrationError#:nodoc:
34
41
  def initialize
35
42
  if defined?(Rails)
36
- super("Migrations are pending; run 'bin/rake db:migrate RAILS_ENV=#{::Rails.env}' to resolve this issue.")
43
+ super("Migrations are pending. To resolve this issue, run:\n\n\tbin/rake db:migrate RAILS_ENV=#{::Rails.env}")
37
44
  else
38
- super("Migrations are pending; run 'bin/rake db:migrate' to resolve this issue.")
45
+ super("Migrations are pending. To resolve this issue, run:\n\n\tbin/rake db:migrate")
39
46
  end
40
47
  end
41
48
  end
@@ -377,23 +384,23 @@ module ActiveRecord
377
384
  class << self
378
385
  attr_accessor :delegate # :nodoc:
379
386
  attr_accessor :disable_ddl_transaction # :nodoc:
380
- end
381
387
 
382
- def self.check_pending!
383
- raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?
384
- end
388
+ def check_pending!
389
+ raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?
390
+ end
385
391
 
386
- def self.method_missing(name, *args, &block) # :nodoc:
387
- (delegate || superclass.delegate).send(name, *args, &block)
388
- end
392
+ def method_missing(name, *args, &block) # :nodoc:
393
+ (delegate || superclass.delegate).send(name, *args, &block)
394
+ end
389
395
 
390
- def self.migrate(direction)
391
- new.migrate direction
392
- end
396
+ def migrate(direction)
397
+ new.migrate direction
398
+ end
393
399
 
394
- # Disable DDL transactions for this migration.
395
- def self.disable_ddl_transaction!
396
- @disable_ddl_transaction = true
400
+ # Disable DDL transactions for this migration.
401
+ def disable_ddl_transaction!
402
+ @disable_ddl_transaction = true
403
+ end
397
404
  end
398
405
 
399
406
  def disable_ddl_transaction # :nodoc:
@@ -620,9 +627,9 @@ module ActiveRecord
620
627
 
621
628
  say_with_time "#{method}(#{arg_list})" do
622
629
  unless @connection.respond_to? :revert
623
- unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method)
624
- arguments[0] = Migrator.proper_table_name(arguments.first)
625
- arguments[1] = Migrator.proper_table_name(arguments.second) if method == :rename_table
630
+ unless arguments.empty? || method == :execute
631
+ arguments[0] = proper_table_name(arguments.first, table_name_options)
632
+ arguments[1] = proper_table_name(arguments.second, table_name_options) if method == :rename_table
626
633
  end
627
634
  end
628
635
  return super unless connection.respond_to?(method)
@@ -675,14 +682,33 @@ module ActiveRecord
675
682
  copied
676
683
  end
677
684
 
685
+ # Finds the correct table name given an Active Record object.
686
+ # Uses the Active Record object's own table_name, or pre/suffix from the
687
+ # options passed in.
688
+ def proper_table_name(name, options = {})
689
+ if name.respond_to? :table_name
690
+ name.table_name
691
+ else
692
+ "#{options[:table_name_prefix]}#{name}#{options[:table_name_suffix]}"
693
+ end
694
+ end
695
+
696
+ # Determines the version number of the next migration.
678
697
  def next_migration_number(number)
679
698
  if ActiveRecord::Base.timestamped_migrations
680
699
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
681
700
  else
682
- SchemaMigration.normalize_migration_number(number)
701
+ "%.3d" % number
683
702
  end
684
703
  end
685
704
 
705
+ def table_name_options(config = ActiveRecord::Base)
706
+ {
707
+ table_name_prefix: config.table_name_prefix,
708
+ table_name_suffix: config.table_name_suffix
709
+ }
710
+ end
711
+
686
712
  private
687
713
  def execute_block
688
714
  if connection.respond_to? :execute_block
@@ -720,7 +746,7 @@ module ActiveRecord
720
746
 
721
747
  def load_migration
722
748
  require(File.expand_path(filename))
723
- name.constantize.new(name, version)
749
+ name.constantize.new
724
750
  end
725
751
 
726
752
  end
@@ -812,12 +838,16 @@ module ActiveRecord
812
838
  migrations(migrations_paths).last || NullMigration.new
813
839
  end
814
840
 
815
- def proper_table_name(name)
816
- # Use the Active Record objects own table_name, or pre/suffix from ActiveRecord::Base if name is a symbol/string
841
+ def proper_table_name(name, options = {})
842
+ ActiveSupport::Deprecation.warn "ActiveRecord::Migrator.proper_table_name is deprecated and will be removed in Rails 4.2. Use the proper_table_name instance method on ActiveRecord::Migration instead"
843
+ options = {
844
+ table_name_prefix: ActiveRecord::Base.table_name_prefix,
845
+ table_name_suffix: ActiveRecord::Base.table_name_suffix
846
+ }.merge(options)
817
847
  if name.respond_to? :table_name
818
848
  name.table_name
819
849
  else
820
- "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}"
850
+ "#{options[:table_name_prefix]}#{name}#{options[:table_name_suffix]}"
821
851
  end
822
852
  end
823
853
 
@@ -869,13 +899,7 @@ module ActiveRecord
869
899
  @direction = direction
870
900
  @target_version = target_version
871
901
  @migrated_versions = nil
872
-
873
- if Array(migrations).grep(String).empty?
874
- @migrations = migrations
875
- else
876
- ActiveSupport::Deprecation.warn "instantiate this class with a list of migrations"
877
- @migrations = self.class.migrations(migrations)
878
- end
902
+ @migrations = migrations
879
903
 
880
904
  validate(@migrations)
881
905
 
@@ -909,15 +933,7 @@ module ActiveRecord
909
933
  raise UnknownMigrationVersionError.new(@target_version)
910
934
  end
911
935
 
912
- running = runnable
913
-
914
- if block_given?
915
- message = "block argument to migrate is deprecated, please filter migrations before constructing the migrator"
916
- ActiveSupport::Deprecation.warn message
917
- running.select! { |m| yield m }
918
- end
919
-
920
- running.each do |migration|
936
+ runnable.each do |migration|
921
937
  Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
922
938
 
923
939
  begin
@@ -73,7 +73,7 @@ module ActiveRecord
73
73
  [:create_table, :create_join_table, :rename_table, :add_column, :remove_column,
74
74
  :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
75
75
  :change_column_default, :add_reference, :remove_reference, :transaction,
76
- :drop_join_table, :drop_table, :execute_block,
76
+ :drop_join_table, :drop_table, :execute_block, :enable_extension,
77
77
  :change_column, :execute, :remove_columns, # irreversible methods need to be here too
78
78
  ].each do |method|
79
79
  class_eval <<-EOV, __FILE__, __LINE__ + 1
@@ -86,7 +86,7 @@ module ActiveRecord
86
86
  alias :remove_belongs_to :remove_reference
87
87
 
88
88
  def change_table(table_name, options = {})
89
- yield delegate.update_table_definition(table_name, self)
89
+ yield ConnectionAdapters::Table.new(table_name, self)
90
90
  end
91
91
 
92
92
  private
@@ -100,6 +100,7 @@ module ActiveRecord
100
100
  add_column: :remove_column,
101
101
  add_timestamps: :remove_timestamps,
102
102
  add_reference: :remove_reference,
103
+ enable_extension: :disable_extension
103
104
  }.each do |cmd, inv|
104
105
  [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
105
106
  class_eval <<-EOV, __FILE__, __LINE__ + 1
@@ -139,12 +140,7 @@ module ActiveRecord
139
140
 
140
141
  def invert_add_index(args)
141
142
  table, columns, options = *args
142
- options ||= {}
143
-
144
- index_name = options[:name]
145
- options_hash = index_name ? { name: index_name } : { column: columns }
146
-
147
- [:remove_index, [table, options_hash]]
143
+ [:remove_index, [table, (options || {}).merge(column: columns)]]
148
144
  end
149
145
 
150
146
  def invert_remove_index(args)
@@ -163,11 +159,9 @@ module ActiveRecord
163
159
 
164
160
  # Forwards any missing method call to the \target.
165
161
  def method_missing(method, *args, &block)
166
- if @delegate.respond_to?(method)
167
- @delegate.send(method, *args, &block)
168
- else
169
- super
170
- end
162
+ @delegate.send(method, *args, &block)
163
+ rescue NoMethodError => e
164
+ raise e, e.message.sub(/ for #<.*$/, " via proxy for #{@delegate}")
171
165
  end
172
166
  end
173
167
  end