aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RELEASING_RAILS.rdoc12
-rw-r--r--activerecord/lib/active_record/attribute.rb19
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb12
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb4
-rw-r--r--activerecord/lib/active_record/migration.rb13
-rw-r--r--activerecord/test/cases/migration/pending_migrations_test.rb50
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb15
7 files changed, 111 insertions, 14 deletions
diff --git a/RELEASING_RAILS.rdoc b/RELEASING_RAILS.rdoc
index c6c1c12e87..f8c40f0b02 100644
--- a/RELEASING_RAILS.rdoc
+++ b/RELEASING_RAILS.rdoc
@@ -25,6 +25,18 @@ for Rails. You can check the status of his tests here:
Do not release with Red AWDwR tests.
+=== Are the supported plugins working? If not, make it work.
+
+Some Rails plugins are important and need to be supported until Rails 5.
+As these plugins are outside the Rails repository it is easy to break then without knowing
+after some refactoring or bug fix, so it is important to check if the following plugins
+are working with the versions that will be released:
+
+* https://github.com/rails/protected_attributes
+* https://github.com/rails/activerecord-deprecated_finders
+
+Do not release red plugins tests.
+
=== Do we have any Git dependencies? If so, contact those authors.
Having Git dependencies indicates that we depend on unreleased code.
diff --git a/activerecord/lib/active_record/attribute.rb b/activerecord/lib/active_record/attribute.rb
index f78cde23c5..8604ccb90d 100644
--- a/activerecord/lib/active_record/attribute.rb
+++ b/activerecord/lib/active_record/attribute.rb
@@ -29,6 +29,14 @@ module ActiveRecord
type.type_cast_for_database(value)
end
+ def changed_from?(old_value)
+ type.changed?(old_value, value, value_before_type_cast)
+ end
+
+ def changed_in_place_from?(old_value)
+ type.changed_in_place?(old_value, value)
+ end
+
def type_cast
raise NotImplementedError
end
@@ -52,5 +60,16 @@ module ActiveRecord
type.type_cast_from_user(value)
end
end
+
+ class Null
+ class << self
+ attr_reader :value, :value_before_type_cast, :value_for_database
+
+ def changed_from?(*)
+ false
+ end
+ alias changed_in_place_from? changed_from?
+ end
+ end
end
end
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 6a5c057384..9d1310b576 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -137,9 +137,7 @@ module ActiveRecord
end
def _field_changed?(attr, old_value)
- new_value = read_attribute(attr)
- raw_value = read_attribute_before_type_cast(attr)
- column_for_attribute(attr).changed?(old_value, new_value, raw_value)
+ attribute_named(attr).changed_from?(old_value)
end
def changed_in_place
@@ -149,10 +147,8 @@ module ActiveRecord
end
def changed_in_place?(attr_name)
- type = type_for_attribute(attr_name)
old_value = original_raw_attribute(attr_name)
- value = read_attribute(attr_name)
- type.changed_in_place?(old_value, value)
+ attribute_named(attr_name).changed_in_place_from?(old_value)
end
def original_raw_attribute(attr_name)
@@ -166,9 +162,7 @@ module ActiveRecord
end
def store_original_raw_attribute(attr_name)
- type = type_for_attribute(attr_name)
- value = type.type_cast_for_database(read_attribute(attr_name))
- original_raw_attributes[attr_name] = value
+ original_raw_attributes[attr_name] = attribute_named(attr_name).value_for_database
end
def store_original_raw_attributes
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 8c1cc128f7..525c46970a 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -99,6 +99,10 @@ module ActiveRecord
def attribute(attribute_name)
read_attribute(attribute_name)
end
+
+ def attribute_named(attribute_name)
+ @attributes.fetch(attribute_name, Attribute::Null)
+ end
end
end
end
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 481e5c17e4..01c001e692 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -366,16 +366,19 @@ module ActiveRecord
# This class is used to verify that all migrations have been run before
# loading a web page if config.active_record.migration_error is set to :page_load
class CheckPending
- def initialize(app)
+ def initialize(app, connection = Base.connection)
@app = app
+ @connection = connection
@last_check = 0
end
def call(env)
- mtime = ActiveRecord::Migrator.last_migration.mtime.to_i
- if @last_check < mtime
- ActiveRecord::Migration.check_pending!
- @last_check = mtime
+ if @connection.supports_migrations?
+ mtime = ActiveRecord::Migrator.last_migration.mtime.to_i
+ if @last_check < mtime
+ ActiveRecord::Migration.check_pending!(@connection)
+ @last_check = mtime
+ end
end
@app.call(env)
end
diff --git a/activerecord/test/cases/migration/pending_migrations_test.rb b/activerecord/test/cases/migration/pending_migrations_test.rb
new file mode 100644
index 0000000000..eff000e1a4
--- /dev/null
+++ b/activerecord/test/cases/migration/pending_migrations_test.rb
@@ -0,0 +1,50 @@
+require 'cases/helper'
+require "minitest/mock"
+
+module ActiveRecord
+ class Migration
+ class PendingMigrationsTest < ActiveRecord::TestCase
+ def setup
+ super
+ @connection = MiniTest::Mock.new
+ @app = MiniTest::Mock.new
+ @pending = CheckPending.new(@app, @connection)
+ @pending.instance_variable_set :@last_check, -1 # Force checking
+ end
+
+ def teardown
+ super
+ assert @connection.verify
+ assert @app.verify
+ end
+
+ def test_errors_if_pending
+ @connection.expect :supports_migrations?, true
+
+ ActiveRecord::Migrator.stub :needs_migration?, true do
+ assert_raise ActiveRecord::PendingMigrationError do
+ @pending.call(nil)
+ end
+ end
+ end
+
+ def test_checks_if_supported
+ @connection.expect :supports_migrations?, true
+ @app.expect :call, nil, [:foo]
+
+ ActiveRecord::Migrator.stub :needs_migration?, false do
+ @pending.call(:foo)
+ end
+ end
+
+ def test_doesnt_check_if_unsupported
+ @connection.expect :supports_migrations?, false
+ @app.expect :call, nil, [:foo]
+
+ ActiveRecord::Migrator.stub :needs_migration?, true do
+ @pending.call(:foo)
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index f18172a5ce..eb8e87cc31 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -691,6 +691,11 @@ class HashExtTest < ActiveSupport::TestCase
{ :failure => "stuff", :funny => "business" }.assert_valid_keys([ :failure, :funny ])
{ :failure => "stuff", :funny => "business" }.assert_valid_keys(:failure, :funny)
end
+ # not all valid keys are required to be present
+ assert_nothing_raised do
+ { :failure => "stuff", :funny => "business" }.assert_valid_keys([ :failure, :funny, :sunny ])
+ { :failure => "stuff", :funny => "business" }.assert_valid_keys(:failure, :funny, :sunny)
+ end
exception = assert_raise ArgumentError do
{ :failore => "stuff", :funny => "business" }.assert_valid_keys([ :failure, :funny ])
@@ -701,6 +706,16 @@ class HashExtTest < ActiveSupport::TestCase
{ :failore => "stuff", :funny => "business" }.assert_valid_keys(:failure, :funny)
end
assert_equal "Unknown key: :failore. Valid keys are: :failure, :funny", exception.message
+
+ exception = assert_raise ArgumentError do
+ { :failore => "stuff", :funny => "business" }.assert_valid_keys([ :failure ])
+ end
+ assert_equal "Unknown key: :failore. Valid keys are: :failure", exception.message
+
+ exception = assert_raise ArgumentError do
+ { :failore => "stuff", :funny => "business" }.assert_valid_keys(:failure)
+ end
+ assert_equal "Unknown key: :failore. Valid keys are: :failure", exception.message
end
def test_assorted_keys_not_stringified