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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +745 -2700
- data/README.rdoc +2 -2
- data/examples/performance.rb +30 -18
- data/examples/simple.rb +4 -4
- data/lib/active_record.rb +2 -6
- data/lib/active_record/aggregations.rb +2 -1
- data/lib/active_record/association_relation.rb +0 -4
- data/lib/active_record/associations.rb +87 -43
- data/lib/active_record/associations/alias_tracker.rb +1 -3
- data/lib/active_record/associations/association.rb +8 -16
- data/lib/active_record/associations/association_scope.rb +5 -16
- data/lib/active_record/associations/belongs_to_association.rb +34 -25
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +78 -54
- data/lib/active_record/associations/builder/belongs_to.rb +91 -58
- data/lib/active_record/associations/builder/collection_association.rb +47 -45
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +107 -25
- data/lib/active_record/associations/builder/has_many.rb +2 -2
- data/lib/active_record/associations/builder/has_one.rb +5 -7
- data/lib/active_record/associations/builder/singular_association.rb +6 -7
- data/lib/active_record/associations/collection_association.rb +68 -105
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/has_many_association.rb +11 -9
- data/lib/active_record/associations/has_many_through_association.rb +16 -12
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +204 -165
- data/lib/active_record/associations/join_dependency/join_association.rb +43 -101
- data/lib/active_record/associations/join_dependency/join_base.rb +6 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +18 -37
- data/lib/active_record/associations/join_helper.rb +2 -11
- data/lib/active_record/associations/preloader.rb +89 -34
- data/lib/active_record/associations/preloader/association.rb +43 -25
- data/lib/active_record/associations/preloader/collection_association.rb +2 -2
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/singular_association.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +58 -26
- data/lib/active_record/associations/singular_association.rb +6 -5
- data/lib/active_record/associations/through_association.rb +2 -2
- data/lib/active_record/attribute_assignment.rb +5 -2
- data/lib/active_record/attribute_methods.rb +45 -40
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -1
- data/lib/active_record/attribute_methods/dirty.rb +8 -22
- data/lib/active_record/attribute_methods/primary_key.rb +1 -7
- data/lib/active_record/attribute_methods/read.rb +55 -28
- data/lib/active_record/attribute_methods/serialization.rb +12 -33
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -13
- data/lib/active_record/attribute_methods/write.rb +37 -12
- data/lib/active_record/autosave_association.rb +207 -207
- data/lib/active_record/base.rb +5 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +2 -7
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +11 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +12 -14
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -5
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +84 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -8
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +52 -83
- data/lib/active_record/connection_adapters/abstract/transaction.rb +0 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +14 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +58 -60
- data/lib/active_record/connection_adapters/column.rb +1 -35
- data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +3 -4
- data/lib/active_record/connection_adapters/mysql_adapter.rb +16 -15
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +24 -18
- data/lib/active_record/connection_adapters/postgresql/cast.rb +20 -16
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +23 -43
- data/lib/active_record/connection_adapters/postgresql/oid.rb +19 -12
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +28 -23
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +8 -30
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +92 -75
- data/lib/active_record/connection_adapters/schema_cache.rb +8 -29
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +31 -64
- data/lib/active_record/connection_handling.rb +2 -2
- data/lib/active_record/core.rb +22 -43
- data/lib/active_record/counter_cache.rb +7 -7
- data/lib/active_record/enum.rb +100 -0
- data/lib/active_record/errors.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +2 -1
- data/lib/active_record/fixtures.rb +171 -74
- data/lib/active_record/inheritance.rb +16 -22
- data/lib/active_record/integration.rb +52 -1
- data/lib/active_record/locking/optimistic.rb +7 -2
- data/lib/active_record/locking/pessimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +5 -12
- data/lib/active_record/migration.rb +62 -46
- data/lib/active_record/migration/command_recorder.rb +7 -13
- data/lib/active_record/model_schema.rb +7 -14
- data/lib/active_record/nested_attributes.rb +10 -8
- data/lib/active_record/no_touching.rb +52 -0
- data/lib/active_record/null_relation.rb +3 -3
- data/lib/active_record/persistence.rb +16 -34
- data/lib/active_record/querying.rb +14 -12
- data/lib/active_record/railtie.rb +0 -50
- data/lib/active_record/railties/databases.rake +12 -15
- data/lib/active_record/readonly_attributes.rb +0 -6
- data/lib/active_record/reflection.rb +189 -75
- data/lib/active_record/relation.rb +69 -94
- data/lib/active_record/relation/batches.rb +57 -23
- data/lib/active_record/relation/calculations.rb +36 -43
- data/lib/active_record/relation/delegation.rb +54 -39
- data/lib/active_record/relation/finder_methods.rb +107 -62
- data/lib/active_record/relation/merger.rb +7 -20
- data/lib/active_record/relation/predicate_builder.rb +57 -38
- data/lib/active_record/relation/predicate_builder/array_handler.rb +29 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
- data/lib/active_record/relation/query_methods.rb +110 -98
- data/lib/active_record/relation/spawn_methods.rb +1 -2
- data/lib/active_record/result.rb +45 -6
- data/lib/active_record/runtime_registry.rb +5 -0
- data/lib/active_record/sanitization.rb +6 -8
- data/lib/active_record/schema_dumper.rb +16 -5
- data/lib/active_record/schema_migration.rb +24 -25
- data/lib/active_record/scoping/default.rb +5 -18
- data/lib/active_record/scoping/named.rb +8 -29
- data/lib/active_record/store.rb +56 -28
- data/lib/active_record/tasks/database_tasks.rb +8 -4
- data/lib/active_record/timestamp.rb +4 -4
- data/lib/active_record/transactions.rb +8 -10
- data/lib/active_record/validations/presence.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +1 -6
- data/lib/active_record/version.rb +1 -1
- data/lib/rails/generators/active_record.rb +2 -8
- data/lib/rails/generators/active_record/migration.rb +18 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +4 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +4 -0
- metadata +32 -45
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -65
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- data/lib/active_record/tasks/firebird_database_tasks.rb +0 -56
- data/lib/active_record/tasks/oracle_database_tasks.rb +0 -45
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +0 -48
- 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
|
-
#
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
-
#
|
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
|
-
|
124
|
-
|
125
|
-
raise
|
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
|
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
|
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
|
-
|
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
|
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(
|
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
|
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
|
-
@
|
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]
|
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
|
-
@
|
66
|
+
@odd = !@odd
|
74
67
|
end
|
75
68
|
|
76
69
|
def logger
|
@@ -1,41 +1,48 @@
|
|
1
|
-
require "active_support/core_ext/
|
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 <
|
13
|
+
class IrreversibleMigration < MigrationError
|
7
14
|
end
|
8
15
|
|
9
|
-
class DuplicateMigrationVersionError <
|
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 <
|
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 <
|
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 <
|
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 <
|
40
|
+
class PendingMigrationError < MigrationError#:nodoc:
|
34
41
|
def initialize
|
35
42
|
if defined?(Rails)
|
36
|
-
super("Migrations are pending
|
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
|
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
|
-
|
383
|
-
|
384
|
-
|
388
|
+
def check_pending!
|
389
|
+
raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?
|
390
|
+
end
|
385
391
|
|
386
|
-
|
387
|
-
|
388
|
-
|
392
|
+
def method_missing(name, *args, &block) # :nodoc:
|
393
|
+
(delegate || superclass.delegate).send(name, *args, &block)
|
394
|
+
end
|
389
395
|
|
390
|
-
|
391
|
-
|
392
|
-
|
396
|
+
def migrate(direction)
|
397
|
+
new.migrate direction
|
398
|
+
end
|
393
399
|
|
394
|
-
|
395
|
-
|
396
|
-
|
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? ||
|
624
|
-
arguments[0] =
|
625
|
-
arguments[1] =
|
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
|
-
|
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
|
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
|
-
|
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
|
-
"#{
|
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
|
-
|
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
|
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
|
-
|
167
|
-
|
168
|
-
|
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
|