aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/Rakefile4
-rw-r--r--activerecord/lib/active_record/base.rb8
-rw-r--r--activerecord/lib/rails/generators/active_record.rb12
-rw-r--r--activerecord/lib/rails/generators/active_record/migration.rb15
-rw-r--r--activerecord/test/cases/base_test.rb15
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb121
-rw-r--r--activerecord/test/cases/relations_test.rb2
-rw-r--r--activerecord/test/schema/schema.rb6
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