diff options
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/Rakefile | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/base.rb | 8 | ||||
-rw-r--r-- | activerecord/lib/rails/generators/active_record.rb | 12 | ||||
-rw-r--r-- | activerecord/lib/rails/generators/active_record/migration.rb | 15 | ||||
-rw-r--r-- | activerecord/test/cases/base_test.rb | 15 | ||||
-rw-r--r-- | activerecord/test/cases/nested_attributes_test.rb | 121 | ||||
-rw-r--r-- | activerecord/test/cases/relations_test.rb | 2 | ||||
-rw-r--r-- | activerecord/test/schema/schema.rb | 6 |
8 files changed, 110 insertions, 73 deletions
diff --git a/activerecord/Rakefile b/activerecord/Rakefile index c2d63cda23..395c72dfbc 100644 --- a/activerecord/Rakefile +++ b/activerecord/Rakefile @@ -75,8 +75,8 @@ end namespace :mysql do desc 'Build the MySQL test databases' task :build_databases do - %x( echo "create DATABASE activerecord_unittest DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci " | mysql --user=#{MYSQL_DB_USER}) - %x( echo "create DATABASE activerecord_unittest2 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci " | mysql --user=#{MYSQL_DB_USER}) + %x( mysql --user=#{MYSQL_DB_USER} -e "create DATABASE activerecord_unittest DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci ") + %x( mysql --user=#{MYSQL_DB_USER} -e "create DATABASE activerecord_unittest2 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci ") end desc 'Drop the MySQL test databases' diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index f465a38dbe..c3a34ae104 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -890,6 +890,10 @@ module ActiveRecord #:nodoc: Thread.current[key] = Thread.current[key].presence || self.default_scoping.dup end + def before_remove_const #:nodoc: + reset_scoped_methods + end + private def relation #:nodoc: @@ -1174,6 +1178,10 @@ MSG scoped_methods.last end + def reset_scoped_methods #:nodoc: + Thread.current[:"#{self}_scoped_methods"] = nil + end + # Returns the class type of the record using the current module as a prefix. So descendants of # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass. def compute_type(type_name) diff --git a/activerecord/lib/rails/generators/active_record.rb b/activerecord/lib/rails/generators/active_record.rb index 5d8a8e81bc..26bc977e19 100644 --- a/activerecord/lib/rails/generators/active_record.rb +++ b/activerecord/lib/rails/generators/active_record.rb @@ -1,27 +1,19 @@ require 'rails/generators/named_base' require 'rails/generators/migration' require 'rails/generators/active_model' +require 'rails/generators/active_record/migration' require 'active_record' module ActiveRecord module Generators class Base < Rails::Generators::NamedBase #:nodoc: include Rails::Generators::Migration + extend ActiveRecord::Generators::Migration # Set the current directory as base for the inherited generators. def self.base_root File.dirname(__FILE__) end - - # Implement the required interface for Rails::Generators::Migration. - def self.next_migration_number(dirname) #:nodoc: - next_migration_number = current_migration_number(dirname) + 1 - if ActiveRecord::Base.timestamped_migrations - [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max - else - "%.3d" % next_migration_number - end - end end end end diff --git a/activerecord/lib/rails/generators/active_record/migration.rb b/activerecord/lib/rails/generators/active_record/migration.rb new file mode 100644 index 0000000000..7f2f2e06a5 --- /dev/null +++ b/activerecord/lib/rails/generators/active_record/migration.rb @@ -0,0 +1,15 @@ +module ActiveRecord + module Generators + module Migration + # Implement the required interface for Rails::Generators::Migration. + def next_migration_number(dirname) #:nodoc: + next_migration_number = current_migration_number(dirname) + 1 + if ActiveRecord::Base.timestamped_migrations + [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max + else + "%.3d" % next_migration_number + end + end + end + end +end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 55f0b1ce21..d58e302cb2 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1415,6 +1415,21 @@ class BasicsTest < ActiveRecord::TestCase end end + def test_default_scope_is_reset + Object.const_set :UnloadablePost, Class.new(ActiveRecord::Base) + UnloadablePost.table_name = 'posts' + UnloadablePost.class_eval do + default_scope order('posts.comments_count ASC') + end + + UnloadablePost.unloadable + assert_not_nil Thread.current[:UnloadablePost_scoped_methods] + ActiveSupport::Dependencies.remove_unloadable_constants! + assert_nil Thread.current[:UnloadablePost_scoped_methods] + ensure + Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost) + end + protected def with_env_tz(new_tz = 'US/Eastern') old_tz, ENV['TZ'] = ENV['TZ'], new_tz diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 01152b074f..9823d7aa0e 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -74,9 +74,9 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") ship = pirate.create_ship(:name => 'Nights Dirty Lightning') - assert_no_difference('Ship.count') do - pirate.update_attributes(:ship_attributes => { '_destroy' => true, :id => ship.id }) - end + pirate.update_attributes(:ship_attributes => { '_destroy' => true, :id => ship.id }) + + assert_nothing_raised(ActiveRecord::RecordNotFound) { pirate.ship.reload } end def test_a_model_should_respond_to_underscore_destroy_and_return_if_it_is_marked_for_destruction @@ -194,28 +194,30 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase def test_should_destroy_an_existing_record_if_there_is_a_matching_id_and_destroy_is_truthy @pirate.ship.destroy + [1, '1', true, 'true'].each do |truth| - @pirate.reload.create_ship(:name => 'Mister Pablo') - assert_difference('Ship.count', -1) do - @pirate.update_attributes(:ship_attributes => { :id => @pirate.ship.id, :_destroy => truth }) - end + ship = @pirate.reload.create_ship(:name => 'Mister Pablo') + @pirate.update_attributes(:ship_attributes => { :id => ship.id, :_destroy => truth }) + + assert_nil @pirate.reload.ship + assert_raise(ActiveRecord::RecordNotFound) { Ship.find(ship.id) } end end def test_should_not_destroy_an_existing_record_if_destroy_is_not_truthy [nil, '0', 0, 'false', false].each do |not_truth| - assert_no_difference('Ship.count') do - @pirate.update_attributes(:ship_attributes => { :id => @pirate.ship.id, :_destroy => not_truth }) - end + @pirate.update_attributes(:ship_attributes => { :id => @pirate.ship.id, :_destroy => not_truth }) + + assert_equal @ship, @pirate.reload.ship end end def test_should_not_destroy_an_existing_record_if_allow_destroy_is_false Pirate.accepts_nested_attributes_for :ship, :allow_destroy => false, :reject_if => proc { |attributes| attributes.empty? } - assert_no_difference('Ship.count') do - @pirate.update_attributes(:ship_attributes => { :id => @pirate.ship.id, :_destroy => '1' }) - end + @pirate.update_attributes(:ship_attributes => { :id => @pirate.ship.id, :_destroy => '1' }) + + assert_equal @ship, @pirate.reload.ship Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } end @@ -236,12 +238,15 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_not_destroy_the_associated_model_until_the_parent_is_saved - assert_no_difference('Ship.count') do - @pirate.attributes = { :ship_attributes => { :id => @ship.id, :_destroy => '1' } } - end - assert_difference('Ship.count', -1) do - @pirate.save - end + @pirate.attributes = { :ship_attributes => { :id => @ship.id, :_destroy => '1' } } + + assert !@pirate.ship.destroyed? + assert @pirate.ship.marked_for_destruction? + + @pirate.save + + assert @pirate.ship.destroyed? + assert_nil @pirate.reload.ship end def test_should_automatically_enable_autosave_on_the_association @@ -254,29 +259,30 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase def test_should_create_new_model_when_nothing_is_there_and_update_only_is_true @ship.delete - assert_difference('Ship.count', 1) do - @pirate.reload.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower' }) - end + + @pirate.reload.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower' }) + + assert_not_nil @pirate.ship end def test_should_update_existing_when_update_only_is_true_and_no_id_is_given @ship.delete @ship = @pirate.create_update_only_ship(:name => 'Nights Dirty Lightning') - assert_no_difference('Ship.count') do - @pirate.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower' }) - end + @pirate.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower' }) + assert_equal 'Mayflower', @ship.reload.name + assert_equal @ship, @pirate.reload.ship end def test_should_update_existing_when_update_only_is_true_and_id_is_given @ship.delete @ship = @pirate.create_update_only_ship(:name => 'Nights Dirty Lightning') - assert_no_difference('Ship.count') do - @pirate.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower', :id => @ship.id }) - end + @pirate.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower', :id => @ship.id }) + assert_equal 'Mayflower', @ship.reload.name + assert_equal @ship, @pirate.reload.ship end def test_should_destroy_existing_when_update_only_is_true_and_id_is_given_and_is_marked_for_destruction @@ -284,9 +290,11 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase @ship.delete @ship = @pirate.create_update_only_ship(:name => 'Nights Dirty Lightning') - assert_difference('Ship.count', -1) do - @pirate.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower', :id => @ship.id, :_destroy => true }) - end + @pirate.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower', :id => @ship.id, :_destroy => true }) + + assert_nil @pirate.reload.ship + assert_raise(ActiveRecord::RecordNotFound) { Ship.find(@ship.id) } + Pirate.accepts_nested_attributes_for :update_only_ship, :update_only => true, :allow_destroy => false end @@ -375,27 +383,24 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase def test_should_destroy_an_existing_record_if_there_is_a_matching_id_and_destroy_is_truthy @ship.pirate.destroy [1, '1', true, 'true'].each do |truth| - @ship.reload.create_pirate(:catchphrase => 'Arr') - assert_difference('Pirate.count', -1) do - @ship.update_attributes(:pirate_attributes => { :id => @ship.pirate.id, :_destroy => truth }) - end + pirate = @ship.reload.create_pirate(:catchphrase => 'Arr') + @ship.update_attributes(:pirate_attributes => { :id => pirate.id, :_destroy => truth }) + assert_raise(ActiveRecord::RecordNotFound) { pirate.reload } end end def test_should_not_destroy_an_existing_record_if_destroy_is_not_truthy [nil, '0', 0, 'false', false].each do |not_truth| - assert_no_difference('Pirate.count') do - @ship.update_attributes(:pirate_attributes => { :id => @ship.pirate.id, :_destroy => not_truth }) - end + @ship.update_attributes(:pirate_attributes => { :id => @ship.pirate.id, :_destroy => not_truth }) + assert_nothing_raised(ActiveRecord::RecordNotFound) { @ship.pirate.reload } end end def test_should_not_destroy_an_existing_record_if_allow_destroy_is_false Ship.accepts_nested_attributes_for :pirate, :allow_destroy => false, :reject_if => proc { |attributes| attributes.empty? } - assert_no_difference('Pirate.count') do - @ship.update_attributes(:pirate_attributes => { :id => @ship.pirate.id, :_destroy => '1' }) - end + @ship.update_attributes(:pirate_attributes => { :id => @ship.pirate.id, :_destroy => '1' }) + assert_nothing_raised(ActiveRecord::RecordNotFound) { @ship.pirate.reload } Ship.accepts_nested_attributes_for :pirate, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } end @@ -409,10 +414,12 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase end def test_should_not_destroy_the_associated_model_until_the_parent_is_saved - assert_no_difference('Pirate.count') do - @ship.attributes = { :pirate_attributes => { :id => @ship.pirate.id, '_destroy' => true } } - end - assert_difference('Pirate.count', -1) { @ship.save } + pirate = @ship.pirate + + @ship.attributes = { :pirate_attributes => { :id => pirate.id, '_destroy' => true } } + assert_nothing_raised(ActiveRecord::RecordNotFound) { Pirate.find(pirate.id) } + @ship.save + assert_raise(ActiveRecord::RecordNotFound) { Pirate.find(pirate.id) } end def test_should_automatically_enable_autosave_on_the_association @@ -421,29 +428,28 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase def test_should_create_new_model_when_nothing_is_there_and_update_only_is_true @pirate.delete - assert_difference('Pirate.count', 1) do - @ship.reload.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr' }) - end + @ship.reload.attributes = { :update_only_pirate_attributes => { :catchphrase => 'Arr' } } + + assert @ship.update_only_pirate.new_record? end def test_should_update_existing_when_update_only_is_true_and_no_id_is_given @pirate.delete @pirate = @ship.create_update_only_pirate(:catchphrase => 'Aye') - assert_no_difference('Pirate.count') do - @ship.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr' }) - end + @ship.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr' }) assert_equal 'Arr', @pirate.reload.catchphrase + assert_equal @pirate, @ship.reload.update_only_pirate end def test_should_update_existing_when_update_only_is_true_and_id_is_given @pirate.delete @pirate = @ship.create_update_only_pirate(:catchphrase => 'Aye') - assert_no_difference('Pirate.count') do - @ship.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr', :id => @pirate.id }) - end + @ship.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr', :id => @pirate.id }) + assert_equal 'Arr', @pirate.reload.catchphrase + assert_equal @pirate, @ship.reload.update_only_pirate end def test_should_destroy_existing_when_update_only_is_true_and_id_is_given_and_is_marked_for_destruction @@ -451,9 +457,10 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase @pirate.delete @pirate = @ship.create_update_only_pirate(:catchphrase => 'Aye') - assert_difference('Pirate.count', -1) do - @ship.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr', :id => @pirate.id, :_destroy => true }) - end + @ship.update_attributes(:update_only_pirate_attributes => { :catchphrase => 'Arr', :id => @pirate.id, :_destroy => true }) + + assert_raise(ActiveRecord::RecordNotFound) { @pirate.reload } + Ship.accepts_nested_attributes_for :update_only_pirate, :update_only => true, :allow_destroy => false end end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index aa75aa27d4..be038bfa74 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -521,7 +521,7 @@ class RelationTest < ActiveRecord::TestCase posts = Post.scoped assert_equal [0], posts.select('comments_count').where('id is not null').group('id').order('id').count.values.uniq - assert_equal 7, posts.where('id is not null').select('comments_count').count + assert_equal 0, posts.where('id is not null').select('comments_count').count assert_equal 7, posts.select('comments_count').count('id') assert_equal 0, posts.select('comments_count').count diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 7657e00800..ea62833d81 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -233,7 +233,7 @@ ActiveRecord::Schema.define do end create_table :items, :force => true do |t| - t.column :name, :integer + t.column :name, :string end create_table :inept_wizards, :force => true do |t| @@ -343,8 +343,8 @@ ActiveRecord::Schema.define do t.decimal :my_house_population, :precision => 2, :scale => 0 t.decimal :decimal_number_with_default, :precision => 3, :scale => 2, :default => 2.78 t.float :temperature - # Oracle supports precision up to 38 - if current_adapter?(:OracleAdapter) + # Oracle/SQLServer supports precision up to 38 + if current_adapter?(:OracleAdapter,:SQLServerAdapter) t.decimal :atoms_in_universe, :precision => 38, :scale => 0 else t.decimal :atoms_in_universe, :precision => 55, :scale => 0 |