aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml14
-rw-r--r--Gemfile4
-rw-r--r--actionpack/lib/action_dispatch/journey/gtg/transition_table.rb4
-rw-r--r--actionpack/test/controller/integration_test.rb8
-rw-r--r--actionview/lib/action_view/helpers/date_helper.rb2
-rw-r--r--activejob/lib/active_job/queue_name.rb2
-rw-r--r--activejob/test/cases/queue_naming_test.rb38
-rw-r--r--activejob/test/integration/queuing_test.rb5
-rw-r--r--activerecord/CHANGELOG.md7
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb15
-rw-r--r--activerecord/lib/active_record/autosave_association.rb4
-rw-r--r--activerecord/lib/active_record/fixtures.rb36
-rw-r--r--activerecord/lib/active_record/querying.rb11
-rw-r--r--activerecord/lib/active_record/result.rb4
-rw-r--r--activerecord/test/cases/associations/eager_test.rb36
-rw-r--r--activerecord/test/cases/autosave_association_test.rb9
-rw-r--r--activerecord/test/cases/fixtures_test.rb19
-rw-r--r--activerecord/test/cases/helper.rb13
-rw-r--r--activerecord/test/cases/result_test.rb4
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb2
-rw-r--r--activerecord/test/models/post.rb9
-rw-r--r--activesupport/lib/active_support/callbacks.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/file/atomic.rb2
-rw-r--r--activesupport/test/inflector_test.rb4
-rw-r--r--railties/lib/rails/generators/app_base.rb4
-rw-r--r--railties/lib/rails/generators/rails/controller/controller_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb3
-rw-r--r--railties/test/application/middleware/cache_test.rb12
-rw-r--r--railties/test/generators/plugin_generator_test.rb4
-rw-r--r--tools/README.md7
-rw-r--r--[-rwxr-xr-x]tools/line_statistics3
-rwxr-xr-xtools/profile5
32 files changed, 185 insertions, 109 deletions
diff --git a/.travis.yml b/.travis.yml
index 520c434f06..2823a5456f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,13 +3,6 @@ script: 'ci/travis.rb'
before_install:
- travis_retry gem install bundler
- "rvm current | grep 'jruby' && export AR_JDBC=true || echo"
-rvm:
- - 1.9.3
- - 2.0.0
- - 2.1
- - ruby-head
- - rbx-2
- - jruby
env:
global:
- JRUBY_OPTS='-J-Xmx1024M'
@@ -22,6 +15,13 @@ env:
- "GEM=ar:sqlite3"
- "GEM=ar:postgresql"
- "GEM=aj:integration"
+rvm:
+ - 1.9.3
+ - 2.0.0
+ - 2.1
+ - ruby-head
+ - rbx-2
+ - jruby
matrix:
allow_failures:
- rvm: 1.9.3
diff --git a/Gemfile b/Gemfile
index 9e486b0d9e..103fb0a35a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -14,8 +14,8 @@ gem 'mocha', '~> 0.14', require: false
gem 'rack-cache', '~> 1.2'
gem 'jquery-rails', '~> 4.0.0.beta2'
-gem 'coffee-rails', '~> 4.0.0'
-gem 'turbolinks', '~> 2.2.3'
+gem 'coffee-rails', '~> 4.1.0'
+gem 'turbolinks'
# require: false so bcrypt is loaded only when has_secure_password is used.
# This is to avoid ActiveModel (and by extension the entire framework)
diff --git a/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb b/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb
index 990d2127ee..1b914f0637 100644
--- a/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb
+++ b/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb
@@ -88,13 +88,13 @@ module ActionDispatch
erb = File.read File.join(viz_dir, 'index.html.erb')
states = "function tt() { return #{to_json}; }"
- fun_routes = paths.shuffle.first(3).map do |ast|
+ fun_routes = paths.sample(3).map do |ast|
ast.map { |n|
case n
when Nodes::Symbol
case n.left
when ':id' then rand(100).to_s
- when ':format' then %w{ xml json }.shuffle.first
+ when ':format' then %w{ xml json }.sample
else
'omg'
end
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index c6380c7ffd..d91a1657b3 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -615,6 +615,8 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
get 'bar', :to => 'application_integration_test/test#index', :as => :bar
mount MountedApp => '/mounted', :as => "mounted"
+ get 'fooz' => proc { |env| [ 200, {'X-Cascade' => 'pass'}, [ "omg" ] ] }, :anchor => false
+ get 'fooz', :to => 'application_integration_test/test#index'
end
def app
@@ -631,6 +633,12 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
assert_equal '/mounted/baz', mounted.baz_path
end
+ test "path after cascade pass" do
+ get '/fooz'
+ assert_equal 'index', response.body
+ assert_equal '/fooz', path
+ end
+
test "route helpers after controller access" do
get '/'
assert_equal '/', empty_string_path
diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb
index 9272bb5c10..01a9747035 100644
--- a/actionview/lib/action_view/helpers/date_helper.rb
+++ b/actionview/lib/action_view/helpers/date_helper.rb
@@ -1035,7 +1035,7 @@ module ActionView
def build_selects_from_types(order)
select = ''
first_visible = order.find { |type| !@options[:"discard_#{type}"] }
- order.reverse.each do |type|
+ order.reverse_each do |type|
separator = separator(type) unless type == first_visible # don't add before first visible field
select.insert(0, separator.to_s + send("select_#{type}").to_s)
end
diff --git a/activejob/lib/active_job/queue_name.rb b/activejob/lib/active_job/queue_name.rb
index d6ac01a921..d167617e4e 100644
--- a/activejob/lib/active_job/queue_name.rb
+++ b/activejob/lib/active_job/queue_name.rb
@@ -24,7 +24,7 @@ module ActiveJob
end
def queue_name_from_part(part_name) #:nodoc:
- queue_name = part_name.to_s.presence || default_queue_name
+ queue_name = part_name || default_queue_name
name_parts = [queue_name_prefix.presence, queue_name]
name_parts.compact.join('_')
end
diff --git a/activejob/test/cases/queue_naming_test.rb b/activejob/test/cases/queue_naming_test.rb
index 4052477543..886f41271a 100644
--- a/activejob/test/cases/queue_naming_test.rb
+++ b/activejob/test/cases/queue_naming_test.rb
@@ -9,8 +9,9 @@ class QueueNamingTest < ActiveSupport::TestCase
end
test 'uses given queue name job' do
+ original_queue_name = HelloJob.queue_name
+
begin
- original_queue_name = HelloJob.queue_name
HelloJob.queue_as :greetings
assert_equal "greetings", HelloJob.new.queue_name
ensure
@@ -18,9 +19,32 @@ class QueueNamingTest < ActiveSupport::TestCase
end
end
+ test 'allows a blank queue name' do
+ original_queue_name = HelloJob.queue_name
+
+ begin
+ HelloJob.queue_as ""
+ assert_equal "", HelloJob.new.queue_name
+ ensure
+ HelloJob.queue_name = original_queue_name
+ end
+ end
+
+ test 'does not use a nil queue name' do
+ original_queue_name = HelloJob.queue_name
+
+ begin
+ HelloJob.queue_as nil
+ assert_equal "default", HelloJob.new.queue_name
+ ensure
+ HelloJob.queue_name = original_queue_name
+ end
+ end
+
test 'evals block given to queue_as to determine queue' do
+ original_queue_name = HelloJob.queue_name
+
begin
- original_queue_name = HelloJob.queue_name
HelloJob.queue_as { :another }
assert_equal "another", HelloJob.new.queue_name
ensure
@@ -29,8 +53,9 @@ class QueueNamingTest < ActiveSupport::TestCase
end
test 'can use arguments to determine queue_name in queue_as block' do
+ original_queue_name = HelloJob.queue_name
+
begin
- original_queue_name = HelloJob.queue_name
HelloJob.queue_as { self.arguments.first=='1' ? :one : :two }
assert_equal "one", HelloJob.new('1').queue_name
assert_equal "two", HelloJob.new('3').queue_name
@@ -40,10 +65,10 @@ class QueueNamingTest < ActiveSupport::TestCase
end
test 'queu_name_prefix prepended to the queue name' do
- begin
- original_queue_name_prefix = ActiveJob::Base.queue_name_prefix
- original_queue_name = HelloJob.queue_name
+ original_queue_name_prefix = ActiveJob::Base.queue_name_prefix
+ original_queue_name = HelloJob.queue_name
+ begin
ActiveJob::Base.queue_name_prefix = 'aj'
HelloJob.queue_as :low
assert_equal 'aj_low', HelloJob.queue_name
@@ -57,5 +82,4 @@ class QueueNamingTest < ActiveSupport::TestCase
job = HelloJob.set(queue: :some_queue).perform_later
assert_equal "some_queue", job.queue_name
end
-
end
diff --git a/activejob/test/integration/queuing_test.rb b/activejob/test/integration/queuing_test.rb
index 779dedb53f..219be11509 100644
--- a/activejob/test/integration/queuing_test.rb
+++ b/activejob/test/integration/queuing_test.rb
@@ -10,9 +10,10 @@ class QueuingTest < ActiveSupport::TestCase
end
test 'should not run jobs queued on a non-listenting queue' do
+ skip if adapter_is?(:inline) || adapter_is?(:sucker_punch)
+ old_queue = TestJob.queue_name
+
begin
- skip if adapter_is?(:inline) || adapter_is?(:sucker_punch)
- old_queue = TestJob.queue_name
TestJob.queue_as :some_other_queue
TestJob.perform_later @id
wait_for_jobs_to_finish_for(2.seconds)
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 6bdb53ac5a..b12d048169 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Fix regression causing `after_create` callbacks to run before associated
+ records are autosaved.
+
+ Fixes #17209.
+
+ *Agis Anastasopoulos*
+
* Honor overridden `rack.test` in Rack environment for the connection
management middleware.
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index ec5c189cd3..c5c4edd090 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -142,11 +142,20 @@ module ActiveRecord
parents = model_cache[join_root]
column_aliases = aliases.column_aliases join_root
- result_set.each { |row_hash|
- parent = parents[row_hash[primary_key]] ||= join_root.instantiate(row_hash, column_aliases)
- construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
+ message_bus = ActiveSupport::Notifications.instrumenter
+
+ payload = {
+ record_count: result_set.length,
+ class_name: join_root.base_klass.name
}
+ message_bus.instrument('instantiation.active_record', payload) do
+ result_set.each { |row_hash|
+ parent = parents[row_hash[primary_key]] ||= join_root.instantiate(row_hash, column_aliases)
+ construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
+ }
+ end
+
parents.values
end
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index c384e8c413..a0d70435fa 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -184,7 +184,9 @@ module ActiveRecord
before_save :before_save_collection_association
define_non_cyclic_method(save_method) { save_collection_association(reflection) }
- after_save save_method
+ # Doesn't use after_save as that would save associations added in after_create/after_update twice
+ after_create save_method
+ after_update save_method
elsif reflection.has_one?
define_method(save_method) { save_has_one_association(reflection) } unless method_defined?(save_method)
# Configures two callbacks instead of a single after_save so that
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 44cc1a079f..125a119b5f 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -870,34 +870,9 @@ module ActiveRecord
end
self.fixture_table_names |= fixture_set_names
- require_fixture_classes(fixture_set_names, self.config)
setup_fixture_accessors(fixture_set_names)
end
- def try_to_load_dependency(file_name)
- require_dependency file_name
- rescue LoadError => e
- unless fixture_class_names.key?(file_name.pluralize)
- if ActiveRecord::Base.logger
- ActiveRecord::Base.logger.warn("Unable to load #{file_name}, make sure you added it to ActiveSupport::TestCase.set_fixture_class")
- ActiveRecord::Base.logger.warn("underlying cause #{e.message} \n\n #{e.backtrace.join("\n")}")
- end
- end
- end
-
- def require_fixture_classes(fixture_set_names = nil, config = ActiveRecord::Base)
- if fixture_set_names
- fixture_set_names = fixture_set_names.map { |n| n.to_s }
- else
- fixture_set_names = fixture_table_names
- end
-
- fixture_set_names.each do |file_name|
- file_name = file_name.singularize if config.pluralize_table_names
- try_to_load_dependency(file_name)
- end
- end
-
def setup_fixture_accessors(fixture_set_names = nil)
fixture_set_names = Array(fixture_set_names || fixture_table_names)
methods = Module.new do
@@ -974,7 +949,7 @@ module ActiveRecord
end
# Instantiate fixtures for every test if requested.
- instantiate_fixtures(config) if use_instantiated_fixtures
+ instantiate_fixtures if use_instantiated_fixtures
end
def teardown_fixtures
@@ -1001,16 +976,9 @@ module ActiveRecord
Hash[fixtures.map { |f| [f.name, f] }]
end
- # for pre_loaded_fixtures, only require the classes once. huge speed improvement
- @@required_fixture_classes = false
-
- def instantiate_fixtures(config)
+ def instantiate_fixtures
if pre_loaded_fixtures
raise RuntimeError, 'Load fixtures before instantiating them.' if ActiveRecord::FixtureSet.all_loaded_fixtures.empty?
- unless @@required_fixture_classes
- self.class.require_fixture_classes ActiveRecord::FixtureSet.all_loaded_fixtures.keys, config
- @@required_fixture_classes = true
- end
ActiveRecord::FixtureSet.instantiate_all_loaded_fixtures(self, load_instances?)
else
raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb
index 45b6b1c925..e8de4db3a7 100644
--- a/activerecord/lib/active_record/querying.rb
+++ b/activerecord/lib/active_record/querying.rb
@@ -39,7 +39,16 @@ module ActiveRecord
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds)
column_types = result_set.column_types.dup
columns_hash.each_key { |k| column_types.delete k }
- result_set.map { |record| instantiate(record, column_types) }
+ message_bus = ActiveSupport::Notifications.instrumenter
+
+ payload = {
+ record_count: result_set.length,
+ class_name: name
+ }
+
+ message_bus.instrument('instantiation.active_record', payload) do
+ result_set.map { |record| instantiate(record, column_types) }
+ end
end
# Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb
index 8405fdaeb9..3a3e65ef32 100644
--- a/activerecord/lib/active_record/result.rb
+++ b/activerecord/lib/active_record/result.rb
@@ -42,6 +42,10 @@ module ActiveRecord
@column_types = column_types
end
+ def length
+ @rows.length
+ end
+
def each
if block_given?
hash_rows.each { |row| yield row }
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index b852bd3536..8234ee95be 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -935,6 +935,42 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_equal 3, authors(:david).posts_with_comments.where("length(comments.body) > 15").references(:comments).count
end
+ def test_association_loading_notification
+ notifications = messages_for('instantiation.active_record') do
+ Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size
+ end
+
+ message = notifications.first
+ payload = message.last
+ count = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size
+
+ # eagerloaded row count should be greater than just developer count
+ assert_operator payload[:record_count], :>, count
+ assert_equal Developer.name, payload[:class_name]
+ end
+
+ def test_base_messages
+ notifications = messages_for('instantiation.active_record') do
+ Developer.all.to_a
+ end
+ message = notifications.first
+ payload = message.last
+
+ assert_equal Developer.all.to_a.count, payload[:record_count]
+ assert_equal Developer.name, payload[:class_name]
+ end
+
+ def messages_for(name)
+ notifications = []
+ ActiveSupport::Notifications.subscribe(name) do |*args|
+ notifications << args
+ end
+ yield
+ notifications
+ ensure
+ ActiveSupport::Notifications.unsubscribe(name)
+ end
+
def test_load_with_sti_sharing_association
assert_queries(2) do #should not do 1 query per subclass
Comment.includes(:post).to_a
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index b2a7d3956d..734fd5fe18 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -1,5 +1,6 @@
require 'cases/helper'
require 'models/bird'
+require 'models/comment'
require 'models/company'
require 'models/customer'
require 'models/developer'
@@ -616,6 +617,14 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
firm.save!
assert !account.persisted?
end
+
+ def test_autosave_new_record_with_after_create_callback
+ post = PostWithAfterCreateCallback.new(title: 'Captain Murphy', body: 'is back')
+ post.comments.build(body: 'foo')
+ post.save!
+
+ assert_not_nil post.author_id
+ end
end
class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 1050047a43..7141d3ee7f 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -822,25 +822,6 @@ class ActiveSupportSubclassWithFixturesTest < ActiveRecord::TestCase
end
end
-class FixtureLoadingTest < ActiveRecord::TestCase
- def test_logs_message_for_failed_dependency_load
- ActiveRecord::Base.logger.expects(:warn).twice
- ActiveRecord::TestCase.try_to_load_dependency('does_not_exist')
- end
-
- def test_does_not_logs_message_for_dependency_that_has_been_defined_with_set_fixture_class
- ActiveRecord::TestCase.set_fixture_class unknown_dead_parrots: DeadParrot
- ActiveRecord::Base.logger.expects(:warn).never
- ActiveRecord::TestCase.try_to_load_dependency('unknown_dead_parrot')
- end
-
- def test_does_not_logs_message_for_successful_dependency_load
- ActiveRecord::TestCase.expects(:require_dependency).with('works_out_fine')
- ActiveRecord::Base.logger.expects(:warn).never
- ActiveRecord::TestCase.try_to_load_dependency('works_out_fine')
- end
-end
-
class CustomNameForFixtureOrModelTest < ActiveRecord::TestCase
ActiveRecord::FixtureSet.reset_cache
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index be635aeef9..f5be8a044b 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -136,19 +136,6 @@ def disable_extension!(extension, connection)
connection.reconnect!
end
-unless ENV['FIXTURE_DEBUG']
- module ActiveRecord::TestFixtures::ClassMethods
- def try_to_load_dependency_with_silence(*args)
- old = ActiveRecord::Base.logger.level
- ActiveRecord::Base.logger.level = ActiveSupport::Logger::ERROR
- try_to_load_dependency_without_silence(*args)
- ActiveRecord::Base.logger.level = old
- end
-
- alias_method_chain :try_to_load_dependency, :silence
- end
-end
-
require "cases/validations_repair_helper"
class ActiveSupport::TestCase
include ActiveRecord::TestFixtures
diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb
index d6decafad9..dec01dfa76 100644
--- a/activerecord/test/cases/result_test.rb
+++ b/activerecord/test/cases/result_test.rb
@@ -10,6 +10,10 @@ module ActiveRecord
])
end
+ test "length" do
+ assert_equal 3, result.length
+ end
+
test "to_hash returns row_hashes" do
assert_equal [
{'col_1' => 'row 1 col 1', 'col_2' => 'row 1 col 2'},
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 93fb502410..2241c41f36 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -19,7 +19,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
def test_dump_schema_information_outputs_lexically_ordered_versions
versions = %w{ 20100101010101 20100201010101 20100301010101 }
- versions.reverse.each do |v|
+ versions.reverse_each do |v|
ActiveRecord::SchemaMigration.create!(:version => v)
end
diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb
index 256b720c9a..67027cbc22 100644
--- a/activerecord/test/models/post.rb
+++ b/activerecord/test/models/post.rb
@@ -219,6 +219,15 @@ class PostThatLoadsCommentsInAnAfterSaveHook < ActiveRecord::Base
end
end
+class PostWithAfterCreateCallback < ActiveRecord::Base
+ self.table_name = 'posts'
+ has_many :comments, foreign_key: :post_id
+
+ after_create do |post|
+ update_attribute(:author_id, comments.first.id)
+ end
+end
+
class PostWithCommentWithDefaultScopeReferencesAssociation < ActiveRecord::Base
self.table_name = 'posts'
has_many :comment_with_default_scope_references_associations, foreign_key: :post_id
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 4bc13f20ca..45231bc101 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -559,7 +559,7 @@ module ActiveSupport
# This is used internally to append, prepend and skip callbacks to the
# CallbackChain.
def __update_callbacks(name) #:nodoc:
- ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target|
+ ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse_each do |target|
chain = target.get_callbacks name
yield target, chain.dup
end
diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb
index 0e7e3ba378..38374af388 100644
--- a/activesupport/lib/active_support/core_ext/file/atomic.rb
+++ b/activesupport/lib/active_support/core_ext/file/atomic.rb
@@ -40,7 +40,7 @@ class File
chown(old_stat.uid, old_stat.gid, file_name)
# This operation will affect filesystem ACL's
chmod(old_stat.mode, file_name)
- rescue Errno::EPERM
+ rescue Errno::EPERM, Errno::EACCES
# Changing file ownership failed, moving on.
end
end
diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb
index 5446c5ec3c..be68bb2e2e 100644
--- a/activesupport/test/inflector_test.rb
+++ b/activesupport/test/inflector_test.rb
@@ -490,8 +490,8 @@ class InflectorTest < ActiveSupport::TestCase
assert_equal [], inflect.uncountables
# restore all the inflections
- singulars.reverse.each { |singular| inflect.singular(*singular) }
- plurals.reverse.each { |plural| inflect.plural(*plural) }
+ singulars.reverse_each { |singular| inflect.singular(*singular) }
+ plurals.reverse_each { |plural| inflect.plural(*plural) }
inflect.uncountable(uncountables)
assert_equal singulars, inflect.singulars
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 0d95bb48e0..1eca86bd30 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -265,11 +265,11 @@ module Rails
end
def coffee_gemfile_entry
- comment = 'Use CoffeeScript for .js.coffee assets and views'
+ comment = 'Use CoffeeScript for .coffee assets and views'
if options.dev? || options.edge?
GemfileEntry.github 'coffee-rails', 'rails/coffee-rails', comment
else
- GemfileEntry.version 'coffee-rails', '~> 4.0.0', comment
+ GemfileEntry.version 'coffee-rails', '~> 4.1.0', comment
end
end
diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb
index a48cc13ed7..df615c88b5 100644
--- a/railties/lib/rails/generators/rails/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb
@@ -12,7 +12,7 @@ module Rails
def add_routes
unless options[:skip_routes]
- actions.reverse.each do |action|
+ actions.reverse_each do |action|
route generate_routing_code(action)
end
end
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
index 28cdfecf81..d492e68357 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
@@ -4,6 +4,9 @@ ENV["RAILS_ENV"] = "test"
require File.expand_path("../../<%= options[:dummy_path] -%>/config/environment.rb", __FILE__)
<% unless options[:skip_active_record] -%>
ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../<%= options[:dummy_path] -%>/db/migrate", __FILE__)]
+<% if options[:mountable] -%>
+ActiveRecord::Migrator.migrations_paths << File.expand_path('../../db/migrate', __FILE__)
+<% end -%>
<% end -%>
require "rails/test_help"
diff --git a/railties/test/application/middleware/cache_test.rb b/railties/test/application/middleware/cache_test.rb
index b4db840e68..c951dabd6c 100644
--- a/railties/test/application/middleware/cache_test.rb
+++ b/railties/test/application/middleware/cache_test.rb
@@ -81,8 +81,8 @@ module ApplicationTests
add_to_config "config.action_dispatch.rack_cache = true"
get "/expires/expires_header"
- assert_equal "miss, ignore, store", last_response.headers["X-Rack-Cache"]
- assert_equal "max-age=10, public", last_response.headers["Cache-Control"]
+ assert_equal "miss, store", last_response.headers["X-Rack-Cache"]
+ assert_equal "max-age=10, public", last_response.headers["Cache-Control"]
body = last_response.body
@@ -115,8 +115,8 @@ module ApplicationTests
add_to_config "config.action_dispatch.rack_cache = true"
get "/expires/expires_etag"
- assert_equal "miss, ignore, store", last_response.headers["X-Rack-Cache"]
- assert_equal "public", last_response.headers["Cache-Control"]
+ assert_equal "miss, store", last_response.headers["X-Rack-Cache"]
+ assert_equal "public", last_response.headers["Cache-Control"]
body = last_response.body
etag = last_response.headers["ETag"]
@@ -149,8 +149,8 @@ module ApplicationTests
add_to_config "config.action_dispatch.rack_cache = true"
get "/expires/expires_last_modified"
- assert_equal "miss, ignore, store", last_response.headers["X-Rack-Cache"]
- assert_equal "public", last_response.headers["Cache-Control"]
+ assert_equal "miss, store", last_response.headers["X-Rack-Cache"]
+ assert_equal "public", last_response.headers["Cache-Control"]
body = last_response.body
last = last_response.headers["Last-Modified"]
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index ed4e100a9b..4329c6e1a4 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -245,6 +245,10 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_match(/stylesheet_link_tag\s+['"]bukkits\/application['"]/, contents)
assert_match(/javascript_include_tag\s+['"]bukkits\/application['"]/, contents)
end
+ assert_file "test/test_helper.rb" do |content|
+ assert_match(/ActiveRecord::Migrator\.migrations_paths.+\.\.\/test\/dummy\/db\/migrate/, content)
+ assert_match(/ActiveRecord::Migrator\.migrations_paths.+<<.+\.\.\/db\/migrate/, content)
+ end
end
def test_creating_gemspec
diff --git a/tools/README.md b/tools/README.md
new file mode 100644
index 0000000000..13be763dac
--- /dev/null
+++ b/tools/README.md
@@ -0,0 +1,7 @@
+## Rails dev tools
+
+This is a collection of utilities used for Rails internal development.
+They aren't used by Rails apps directly.
+
+ * `console` drops you in irb and loads this local Rails repos
+ * `profile` profiles `Kernel#require` to help reduce startup times
diff --git a/tools/line_statistics b/tools/line_statistics
index 5eb5cfdc3d..bfa921b095 100755..100644
--- a/tools/line_statistics
+++ b/tools/line_statistics
@@ -1,4 +1,5 @@
-#!/usr/bin/env ruby
+# Class used to calculates LOC for a provided file list.
+#
# Example:
# files = FileList["lib/active_record/**/*.rb"]
# CodeTools::LineStatistics.new(files).print_loc
diff --git a/tools/profile b/tools/profile
index a35dd18b77..eb7fc7792b 100755
--- a/tools/profile
+++ b/tools/profile
@@ -1,4 +1,7 @@
#!/usr/bin/env ruby
+# Profile require calls giving information about the time and the files that are called
+# when loading the provided file.
+#
# Example:
# tools/profile activesupport/lib/active_support.rb [ruby-prof mode] [ruby-prof printer]
ENV['NO_RELOAD'] ||= '1'
@@ -65,7 +68,7 @@ module CodeTools
private
def assert_ruby_file_exists(path)
- fail Error.new("No such file") unless File.exists?(path)
+ fail Error.new("No such file") unless File.exist?(path)
fail Error.new("#{path} is a directory") if File.directory?(path)
ruby_extension = File.extname(path) == '.rb'
ruby_executable = File.open(path, 'rb') {|f| f.readline } =~ [/\A#!.*ruby/]