activerecord 3.1.12 → 3.2.22.1
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 +804 -338
- data/README.rdoc +3 -3
- data/examples/performance.rb +20 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +3 -6
- data/lib/active_record/associations/association.rb +13 -45
- data/lib/active_record/associations/association_scope.rb +3 -15
- data/lib/active_record/associations/belongs_to_association.rb +1 -1
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +2 -1
- data/lib/active_record/associations/builder/association.rb +6 -4
- data/lib/active_record/associations/builder/belongs_to.rb +7 -4
- data/lib/active_record/associations/builder/collection_association.rb +2 -2
- data/lib/active_record/associations/builder/has_many.rb +4 -4
- data/lib/active_record/associations/builder/has_one.rb +5 -6
- data/lib/active_record/associations/builder/singular_association.rb +3 -16
- data/lib/active_record/associations/collection_association.rb +65 -32
- data/lib/active_record/associations/collection_proxy.rb +8 -41
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -0
- data/lib/active_record/associations/has_many_association.rb +11 -7
- data/lib/active_record/associations/has_many_through_association.rb +19 -9
- data/lib/active_record/associations/has_one_association.rb +23 -13
- data/lib/active_record/associations/join_dependency/join_association.rb +6 -1
- data/lib/active_record/associations/join_dependency.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +3 -3
- data/lib/active_record/associations/preloader.rb +14 -10
- data/lib/active_record/associations/through_association.rb +8 -4
- data/lib/active_record/associations.rb +92 -76
- data/lib/active_record/attribute_assignment.rb +221 -0
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
- data/lib/active_record/attribute_methods/dirty.rb +21 -11
- data/lib/active_record/attribute_methods/primary_key.rb +62 -25
- data/lib/active_record/attribute_methods/read.rb +73 -83
- data/lib/active_record/attribute_methods/serialization.rb +120 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -14
- data/lib/active_record/attribute_methods/write.rb +32 -6
- data/lib/active_record/attribute_methods.rb +231 -30
- data/lib/active_record/autosave_association.rb +44 -26
- data/lib/active_record/base.rb +227 -1708
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +150 -148
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +85 -29
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +7 -34
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +10 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +7 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +39 -28
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +48 -19
- data/lib/active_record/connection_adapters/abstract_adapter.rb +77 -42
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +676 -0
- data/lib/active_record/connection_adapters/column.rb +37 -11
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +133 -581
- data/lib/active_record/connection_adapters/mysql_adapter.rb +136 -693
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +209 -97
- data/lib/active_record/connection_adapters/schema_cache.rb +69 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -6
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +62 -35
- data/lib/active_record/counter_cache.rb +9 -4
- data/lib/active_record/dynamic_finder_match.rb +12 -0
- data/lib/active_record/dynamic_matchers.rb +84 -0
- data/lib/active_record/errors.rb +11 -1
- data/lib/active_record/explain.rb +86 -0
- data/lib/active_record/explain_subscriber.rb +25 -0
- data/lib/active_record/fixtures/file.rb +65 -0
- data/lib/active_record/fixtures.rb +57 -86
- data/lib/active_record/identity_map.rb +3 -4
- data/lib/active_record/inheritance.rb +174 -0
- data/lib/active_record/integration.rb +60 -0
- data/lib/active_record/locking/optimistic.rb +33 -26
- data/lib/active_record/locking/pessimistic.rb +23 -1
- data/lib/active_record/log_subscriber.rb +8 -4
- data/lib/active_record/migration/command_recorder.rb +8 -8
- data/lib/active_record/migration.rb +68 -35
- data/lib/active_record/model_schema.rb +368 -0
- data/lib/active_record/nested_attributes.rb +60 -24
- data/lib/active_record/persistence.rb +57 -11
- data/lib/active_record/query_cache.rb +6 -6
- data/lib/active_record/querying.rb +58 -0
- data/lib/active_record/railtie.rb +37 -29
- data/lib/active_record/railties/controller_runtime.rb +3 -1
- data/lib/active_record/railties/databases.rake +213 -117
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +26 -0
- data/lib/active_record/reflection.rb +7 -15
- data/lib/active_record/relation/batches.rb +7 -4
- data/lib/active_record/relation/calculations.rb +55 -16
- data/lib/active_record/relation/delegation.rb +49 -0
- data/lib/active_record/relation/finder_methods.rb +16 -11
- data/lib/active_record/relation/predicate_builder.rb +8 -6
- data/lib/active_record/relation/query_methods.rb +75 -9
- data/lib/active_record/relation/spawn_methods.rb +48 -7
- data/lib/active_record/relation.rb +78 -32
- data/lib/active_record/result.rb +10 -4
- data/lib/active_record/sanitization.rb +194 -0
- data/lib/active_record/schema_dumper.rb +12 -5
- data/lib/active_record/scoping/default.rb +142 -0
- data/lib/active_record/scoping/named.rb +200 -0
- data/lib/active_record/scoping.rb +152 -0
- data/lib/active_record/serialization.rb +1 -43
- data/lib/active_record/serializers/xml_serializer.rb +4 -45
- data/lib/active_record/session_store.rb +18 -16
- data/lib/active_record/store.rb +52 -0
- data/lib/active_record/test_case.rb +11 -7
- data/lib/active_record/timestamp.rb +17 -3
- data/lib/active_record/transactions.rb +27 -6
- data/lib/active_record/translation.rb +22 -0
- data/lib/active_record/validations/associated.rb +5 -4
- data/lib/active_record/validations/uniqueness.rb +8 -8
- data/lib/active_record/validations.rb +1 -1
- data/lib/active_record/version.rb +3 -3
- data/lib/active_record.rb +38 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb +12 -3
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -1
- data/lib/rails/generators/active_record/model/templates/migration.rb +3 -5
- data/lib/rails/generators/active_record/model/templates/model.rb +5 -0
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +1 -5
- metadata +49 -28
- data/lib/active_record/named_scope.rb +0 -200
@@ -26,13 +26,17 @@ module ActiveRecord
|
|
26
26
|
|
27
27
|
return if 'SCHEMA' == payload[:name]
|
28
28
|
|
29
|
-
name
|
30
|
-
sql
|
31
|
-
binds
|
29
|
+
name = '%s (%.1fms)' % [payload[:name], event.duration]
|
30
|
+
sql = payload[:sql].squeeze(' ')
|
31
|
+
binds = nil
|
32
32
|
|
33
33
|
unless (payload[:binds] || []).empty?
|
34
34
|
binds = " " + payload[:binds].map { |col,v|
|
35
|
-
|
35
|
+
if col
|
36
|
+
[col.name, v]
|
37
|
+
else
|
38
|
+
[nil, v]
|
39
|
+
end
|
36
40
|
}.inspect
|
37
41
|
end
|
38
42
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
class Migration
|
3
|
-
# ActiveRecord::Migration::CommandRecorder records commands done during
|
4
|
-
# a migration and knows how to reverse those commands.
|
3
|
+
# <tt>ActiveRecord::Migration::CommandRecorder</tt> records commands done during
|
4
|
+
# a migration and knows how to reverse those commands. The CommandRecorder
|
5
5
|
# knows how to invert the following commands:
|
6
6
|
#
|
7
7
|
# * add_column
|
8
8
|
# * add_index
|
9
|
-
# *
|
9
|
+
# * add_timestamps
|
10
10
|
# * create_table
|
11
11
|
# * remove_timestamps
|
12
12
|
# * rename_column
|
@@ -20,21 +20,21 @@ module ActiveRecord
|
|
20
20
|
@delegate = delegate
|
21
21
|
end
|
22
22
|
|
23
|
-
# record +command+.
|
23
|
+
# record +command+. +command+ should be a method name and arguments.
|
24
24
|
# For example:
|
25
25
|
#
|
26
|
-
# recorder.record(:method_name, [:arg1, arg2])
|
26
|
+
# recorder.record(:method_name, [:arg1, :arg2])
|
27
27
|
def record(*command)
|
28
28
|
@commands << command
|
29
29
|
end
|
30
30
|
|
31
31
|
# Returns a list that represents commands that are the inverse of the
|
32
|
-
# commands stored in +commands+.
|
32
|
+
# commands stored in +commands+. For example:
|
33
33
|
#
|
34
34
|
# recorder.record(:rename_table, [:old, :new])
|
35
35
|
# recorder.inverse # => [:rename_table, [:new, :old]]
|
36
36
|
#
|
37
|
-
# This method will raise an IrreversibleMigration exception if it cannot
|
37
|
+
# This method will raise an +IrreversibleMigration+ exception if it cannot
|
38
38
|
# invert the +commands+.
|
39
39
|
def inverse
|
40
40
|
@commands.reverse.map { |name, args|
|
@@ -59,7 +59,7 @@ module ActiveRecord
|
|
59
59
|
private
|
60
60
|
|
61
61
|
def invert_create_table(args)
|
62
|
-
[:drop_table, args]
|
62
|
+
[:drop_table, [args.first]]
|
63
63
|
end
|
64
64
|
|
65
65
|
def invert_rename_table(args)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "active_support/core_ext/module/delegation"
|
2
2
|
require "active_support/core_ext/class/attribute_accessors"
|
3
3
|
require "active_support/core_ext/array/wrap"
|
4
|
+
require 'active_support/deprecation'
|
4
5
|
|
5
6
|
module ActiveRecord
|
6
7
|
# Exception that can be raised to stop migrations from going backwards.
|
@@ -68,9 +69,9 @@ module ActiveRecord
|
|
68
69
|
# create_table :system_settings do |t|
|
69
70
|
# t.string :name
|
70
71
|
# t.string :label
|
71
|
-
# t.text
|
72
|
+
# t.text :value
|
72
73
|
# t.string :type
|
73
|
-
# t.integer
|
74
|
+
# t.integer :position
|
74
75
|
# end
|
75
76
|
#
|
76
77
|
# SystemSetting.create :name => "notice",
|
@@ -116,8 +117,9 @@ module ActiveRecord
|
|
116
117
|
# +column_names+ from the table called +table_name+.
|
117
118
|
# * <tt>add_index(table_name, column_names, options)</tt>: Adds a new index
|
118
119
|
# with the name of the column. Other options include
|
119
|
-
# <tt>:name</tt
|
120
|
-
# <tt>{ :name => "users_name_index", :unique => true }</tt>)
|
120
|
+
# <tt>:name</tt>, <tt>:unique</tt> (e.g.
|
121
|
+
# <tt>{ :name => "users_name_index", :unique => true }</tt>) and <tt>:order</tt>
|
122
|
+
# (e.g. { :order => {:name => :desc} }</tt>).
|
121
123
|
# * <tt>remove_index(table_name, :column => column_name)</tt>: Removes the index
|
122
124
|
# specified by +column_name+.
|
123
125
|
# * <tt>remove_index(table_name, :name => index_name)</tt>: Removes the index
|
@@ -183,7 +185,7 @@ module ActiveRecord
|
|
183
185
|
#
|
184
186
|
# class RemoveEmptyTags < ActiveRecord::Migration
|
185
187
|
# def up
|
186
|
-
# Tag.
|
188
|
+
# Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
|
187
189
|
# end
|
188
190
|
#
|
189
191
|
# def down
|
@@ -229,7 +231,7 @@ module ActiveRecord
|
|
229
231
|
# def up
|
230
232
|
# add_column :people, :salary, :integer
|
231
233
|
# Person.reset_column_information
|
232
|
-
# Person.
|
234
|
+
# Person.all.each do |p|
|
233
235
|
# p.update_attribute :salary, SalaryCalculator.compute(p)
|
234
236
|
# end
|
235
237
|
# end
|
@@ -249,7 +251,7 @@ module ActiveRecord
|
|
249
251
|
# def up
|
250
252
|
# ...
|
251
253
|
# say_with_time "Updating salaries..." do
|
252
|
-
# Person.
|
254
|
+
# Person.all.each do |p|
|
253
255
|
# p.update_attribute :salary, SalaryCalculator.compute(p)
|
254
256
|
# end
|
255
257
|
# end
|
@@ -301,7 +303,7 @@ module ActiveRecord
|
|
301
303
|
#
|
302
304
|
# class TenderloveMigration < ActiveRecord::Migration
|
303
305
|
# def change
|
304
|
-
# create_table(:horses) do
|
306
|
+
# create_table(:horses) do |t|
|
305
307
|
# t.column :content, :text
|
306
308
|
# t.column :remind_at, :datetime
|
307
309
|
# end
|
@@ -344,12 +346,24 @@ module ActiveRecord
|
|
344
346
|
@name = self.class.name
|
345
347
|
@version = nil
|
346
348
|
@connection = nil
|
349
|
+
@reverting = false
|
347
350
|
end
|
348
351
|
|
349
352
|
# instantiate the delegate object after initialize is defined
|
350
353
|
self.verbose = true
|
351
354
|
self.delegate = new
|
352
355
|
|
356
|
+
def revert
|
357
|
+
@reverting = true
|
358
|
+
yield
|
359
|
+
ensure
|
360
|
+
@reverting = false
|
361
|
+
end
|
362
|
+
|
363
|
+
def reverting?
|
364
|
+
@reverting
|
365
|
+
end
|
366
|
+
|
353
367
|
def up
|
354
368
|
self.class.delegate = self
|
355
369
|
return unless self.class.respond_to?(:up)
|
@@ -383,9 +397,11 @@ module ActiveRecord
|
|
383
397
|
end
|
384
398
|
@connection = conn
|
385
399
|
time = Benchmark.measure {
|
386
|
-
|
387
|
-
|
388
|
-
|
400
|
+
self.revert {
|
401
|
+
recorder.inverse.each do |cmd, args|
|
402
|
+
send(cmd, *args)
|
403
|
+
end
|
404
|
+
}
|
389
405
|
}
|
390
406
|
else
|
391
407
|
time = Benchmark.measure { change }
|
@@ -440,8 +456,11 @@ module ActiveRecord
|
|
440
456
|
arg_list = arguments.map{ |a| a.inspect } * ', '
|
441
457
|
|
442
458
|
say_with_time "#{method}(#{arg_list})" do
|
443
|
-
unless
|
444
|
-
arguments
|
459
|
+
unless reverting?
|
460
|
+
unless arguments.empty? || method == :execute
|
461
|
+
arguments[0] = Migrator.proper_table_name(arguments.first) unless method == :assume_migrated_upto_version
|
462
|
+
arguments[1] = Migrator.proper_table_name(arguments.second) if method == :rename_table
|
463
|
+
end
|
445
464
|
end
|
446
465
|
return super unless connection.respond_to?(method)
|
447
466
|
connection.send(method, *arguments, &block)
|
@@ -455,26 +474,28 @@ module ActiveRecord
|
|
455
474
|
|
456
475
|
destination_migrations = ActiveRecord::Migrator.migrations(destination)
|
457
476
|
last = destination_migrations.last
|
458
|
-
sources.each do |
|
477
|
+
sources.each do |scope, path|
|
459
478
|
source_migrations = ActiveRecord::Migrator.migrations(path)
|
460
479
|
|
461
480
|
source_migrations.each do |migration|
|
462
481
|
source = File.read(migration.filename)
|
463
|
-
source = "# This migration comes from #{
|
482
|
+
source = "# This migration comes from #{scope} (originally #{migration.version})\n#{source}"
|
464
483
|
|
465
484
|
if duplicate = destination_migrations.detect { |m| m.name == migration.name }
|
466
|
-
options[:on_skip]
|
485
|
+
if options[:on_skip] && duplicate.scope != scope.to_s
|
486
|
+
options[:on_skip].call(scope, migration)
|
487
|
+
end
|
467
488
|
next
|
468
489
|
end
|
469
490
|
|
470
491
|
migration.version = next_migration_number(last ? last.version + 1 : 0).to_i
|
471
|
-
new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.rb")
|
492
|
+
new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.#{scope}.rb")
|
472
493
|
old_path, migration.filename = migration.filename, new_path
|
473
494
|
last = migration
|
474
495
|
|
475
|
-
|
496
|
+
File.open(migration.filename, "w") { |f| f.write source }
|
476
497
|
copied << migration
|
477
|
-
options[:on_copy].call(
|
498
|
+
options[:on_copy].call(scope, migration, old_path) if options[:on_copy]
|
478
499
|
destination_migrations << migration
|
479
500
|
end
|
480
501
|
end
|
@@ -493,9 +514,9 @@ module ActiveRecord
|
|
493
514
|
|
494
515
|
# MigrationProxy is used to defer loading of the actual migration classes
|
495
516
|
# until they are needed
|
496
|
-
class MigrationProxy < Struct.new(:name, :version, :filename)
|
517
|
+
class MigrationProxy < Struct.new(:name, :version, :filename, :scope)
|
497
518
|
|
498
|
-
def initialize(name, version, filename)
|
519
|
+
def initialize(name, version, filename, scope)
|
499
520
|
super
|
500
521
|
@migration = nil
|
501
522
|
end
|
@@ -504,7 +525,7 @@ module ActiveRecord
|
|
504
525
|
File.basename(filename)
|
505
526
|
end
|
506
527
|
|
507
|
-
delegate :migrate, :announce, :write, :to
|
528
|
+
delegate :migrate, :announce, :write, :to => :migration
|
508
529
|
|
509
530
|
private
|
510
531
|
|
@@ -524,16 +545,16 @@ module ActiveRecord
|
|
524
545
|
attr_writer :migrations_paths
|
525
546
|
alias :migrations_path= :migrations_paths=
|
526
547
|
|
527
|
-
def migrate(migrations_paths, target_version = nil)
|
548
|
+
def migrate(migrations_paths, target_version = nil, &block)
|
528
549
|
case
|
529
550
|
when target_version.nil?
|
530
|
-
up(migrations_paths, target_version)
|
551
|
+
up(migrations_paths, target_version, &block)
|
531
552
|
when current_version == 0 && target_version == 0
|
532
553
|
[]
|
533
554
|
when current_version > target_version
|
534
|
-
down(migrations_paths, target_version)
|
555
|
+
down(migrations_paths, target_version, &block)
|
535
556
|
else
|
536
|
-
up(migrations_paths, target_version)
|
557
|
+
up(migrations_paths, target_version, &block)
|
537
558
|
end
|
538
559
|
end
|
539
560
|
|
@@ -545,12 +566,12 @@ module ActiveRecord
|
|
545
566
|
move(:up, migrations_paths, steps)
|
546
567
|
end
|
547
568
|
|
548
|
-
def up(migrations_paths, target_version = nil)
|
549
|
-
self.new(:up, migrations_paths, target_version).migrate
|
569
|
+
def up(migrations_paths, target_version = nil, &block)
|
570
|
+
self.new(:up, migrations_paths, target_version).migrate(&block)
|
550
571
|
end
|
551
572
|
|
552
|
-
def down(migrations_paths, target_version = nil)
|
553
|
-
self.new(:down, migrations_paths, target_version).migrate
|
573
|
+
def down(migrations_paths, target_version = nil, &block)
|
574
|
+
self.new(:down, migrations_paths, target_version).migrate(&block)
|
554
575
|
end
|
555
576
|
|
556
577
|
def run(direction, migrations_paths, target_version)
|
@@ -590,15 +611,23 @@ module ActiveRecord
|
|
590
611
|
migrations_paths.first
|
591
612
|
end
|
592
613
|
|
593
|
-
def migrations(paths)
|
614
|
+
def migrations(paths, *args)
|
615
|
+
if args.empty?
|
616
|
+
subdirectories = true
|
617
|
+
else
|
618
|
+
subdirectories = args.first
|
619
|
+
ActiveSupport::Deprecation.warn "The `subdirectories` argument to `migrations` is deprecated"
|
620
|
+
end
|
621
|
+
|
594
622
|
paths = Array.wrap(paths)
|
595
623
|
|
596
|
-
|
624
|
+
glob = subdirectories ? "**/" : ""
|
625
|
+
files = Dir[*paths.map { |p| "#{p}/#{glob}[0-9]*_*.rb" }]
|
597
626
|
|
598
627
|
seen = Hash.new false
|
599
628
|
|
600
629
|
migrations = files.map do |file|
|
601
|
-
version, name = file.scan(/([0-9]+)_([_a-z0-9]*)
|
630
|
+
version, name, scope = file.scan(/([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/).first
|
602
631
|
|
603
632
|
raise IllegalMigrationNameError.new(file) unless version
|
604
633
|
version = version.to_i
|
@@ -609,7 +638,7 @@ module ActiveRecord
|
|
609
638
|
|
610
639
|
seen[version] = seen[name] = true
|
611
640
|
|
612
|
-
MigrationProxy.new(name, version, file)
|
641
|
+
MigrationProxy.new(name, version, file, scope)
|
613
642
|
end
|
614
643
|
|
615
644
|
migrations.sort_by(&:version)
|
@@ -652,7 +681,7 @@ module ActiveRecord
|
|
652
681
|
end
|
653
682
|
end
|
654
683
|
|
655
|
-
def migrate
|
684
|
+
def migrate(&block)
|
656
685
|
current = migrations.detect { |m| m.version == current_version }
|
657
686
|
target = migrations.detect { |m| m.version == @target_version }
|
658
687
|
|
@@ -669,6 +698,10 @@ module ActiveRecord
|
|
669
698
|
|
670
699
|
ran = []
|
671
700
|
runnable.each do |migration|
|
701
|
+
if block && !block.call(migration)
|
702
|
+
next
|
703
|
+
end
|
704
|
+
|
672
705
|
Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
|
673
706
|
|
674
707
|
seen = migrated.include?(migration.version.to_i)
|