aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Gemfile2
-rw-r--r--Rakefile5
-rw-r--r--actionmailer/actionmailer.gemspec2
-rw-r--r--actionmailer/lib/action_mailer/base.rb3
-rw-r--r--actionmailer/lib/action_mailer/old_api.rb1
-rw-r--r--actionmailer/lib/action_mailer/railtie.rb6
-rw-r--r--actionmailer/test/base_test.rb34
-rw-r--r--actionmailer/test/old_base/mail_service_test.rb6
-rw-r--r--actionpack/lib/action_controller/base.rb3
-rw-r--r--actionpack/lib/action_controller/deprecated/base.rb12
-rw-r--r--actionpack/lib/action_controller/metal/cookies.rb1
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb1
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb1
-rw-r--r--actionpack/lib/action_controller/railtie.rb10
-rw-r--r--actionpack/lib/action_controller/railties/log_subscriber.rb2
-rw-r--r--actionpack/lib/action_controller/railties/url_helpers.rb6
-rw-r--r--actionpack/lib/action_controller/record_identifier.rb4
-rw-r--r--actionpack/lib/action_controller/test_case.rb11
-rw-r--r--actionpack/lib/action_dispatch/http/cache.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/filter_parameters.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb8
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb1
-rwxr-xr-xactionpack/lib/action_dispatch/http/request.rb6
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/upload.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb1
-rw-r--r--actionpack/lib/action_dispatch/routing/deprecated_mapper.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb69
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb20
-rw-r--r--actionpack/lib/action_dispatch/testing/performance_test.rb4
-rw-r--r--actionpack/lib/action_dispatch/testing/test_request.rb2
-rw-r--r--actionpack/lib/action_view/base.rb2
-rw-r--r--actionpack/lib/action_view/helpers/active_model_helper.rb23
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb71
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb1
-rw-r--r--actionpack/lib/action_view/railtie.rb4
-rw-r--r--actionpack/lib/action_view/render/partials.rb2
-rw-r--r--actionpack/lib/action_view/template/resolver.rb7
-rw-r--r--actionpack/lib/action_view/test_case.rb1
-rw-r--r--actionpack/test/abstract_unit.rb15
-rw-r--r--actionpack/test/activerecord/polymorphic_routes_test.rb164
-rw-r--r--actionpack/test/controller/caching_test.rb6
-rw-r--r--actionpack/test/controller/cookie_test.rb2
-rw-r--r--actionpack/test/controller/integration_test.rb47
-rw-r--r--actionpack/test/controller/resources_test.rb14
-rw-r--r--actionpack/test/controller/test_test.rb8
-rw-r--r--actionpack/test/controller/url_rewriter_test.rb28
-rw-r--r--actionpack/test/controller/webservice_test.rb2
-rw-r--r--actionpack/test/dispatch/rack_test.rb6
-rw-r--r--actionpack/test/dispatch/request_test.rb8
-rw-r--r--actionpack/test/dispatch/routing_test.rb45
-rw-r--r--actionpack/test/template/active_model_helper_test.rb4
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb16
-rw-r--r--actionpack/test/template/test_case_test.rb2
-rw-r--r--activemodel/lib/active_model/dirty.rb3
-rw-r--r--activemodel/lib/active_model/errors.rb1
-rw-r--r--activemodel/lib/active_model/validations/inclusion.rb2
-rw-r--r--activemodel/lib/active_model/validator.rb1
-rw-r--r--activerecord/CHANGELOG6
-rw-r--r--activerecord/lib/active_record.rb6
-rw-r--r--activerecord/lib/active_record/association_preload.rb7
-rwxr-xr-xactiverecord/lib/active_record/associations.rb42
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb1
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb22
-rw-r--r--activerecord/lib/active_record/attribute_methods/query.rb2
-rwxr-xr-xactiverecord/lib/active_record/base.rb18
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb13
-rw-r--r--activerecord/lib/active_record/fixtures.rb1
-rw-r--r--activerecord/lib/active_record/named_scope.rb13
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb1
-rw-r--r--activerecord/lib/active_record/query_cache.rb2
-rw-r--r--activerecord/lib/active_record/railtie.rb16
-rw-r--r--activerecord/lib/active_record/relation.rb2
-rw-r--r--activerecord/lib/active_record/relation/batches.rb8
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb2
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb2
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb7
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb2
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb2
-rw-r--r--activerecord/lib/active_record/schema.rb2
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb6
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb26
-rw-r--r--activerecord/test/cases/associations/eager_test.rb6
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb8
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb10
-rw-r--r--activerecord/test/cases/batches_test.rb16
-rw-r--r--activerecord/test/cases/modules_test.rb28
-rw-r--r--activerecord/test/cases/named_scope_test.rb23
-rw-r--r--activerecord/test/cases/pk_test.rb6
-rw-r--r--activerecord/test/models/company.rb5
-rw-r--r--activerecord/test/models/company_in_module.rb17
-rw-r--r--activeresource/lib/active_resource/base.rb1
-rw-r--r--activeresource/lib/active_resource/custom_methods.rb2
-rw-r--r--activeresource/lib/active_resource/validations.rb1
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/cache/mem_cache_store.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/keys.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/time/marshal.rb56
-rw-r--r--activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb26
-rw-r--r--activesupport/lib/active_support/dependencies/autoload.rb4
-rw-r--r--activesupport/lib/active_support/i18n.rb2
-rw-r--r--activesupport/lib/active_support/lazy_load_hooks.rb30
-rw-r--r--activesupport/lib/active_support/railtie.rb2
-rw-r--r--activesupport/lib/active_support/testing/assertions.rb15
-rw-r--r--activesupport/lib/active_support/time.rb2
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb7
-rw-r--r--activesupport/lib/active_support/xml_mini/libxmlsax.rb1
-rw-r--r--activesupport/lib/active_support/xml_mini/nokogirisax.rb1
-rw-r--r--activesupport/lib/active_support/xml_mini/rexml.rb8
-rw-r--r--activesupport/test/abstract_unit.rb1
-rw-r--r--activesupport/test/caching_test.rb6
-rw-r--r--activesupport/test/core_ext/blank_test.rb8
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb20
-rw-r--r--activesupport/test/empty_bool.rb7
-rw-r--r--activesupport/test/message_encryptor_test.rb2
-rw-r--r--activesupport/test/message_verifier_test.rb2
-rw-r--r--activesupport/test/test_test.rb40
-rwxr-xr-xci/ci_build.rb2
-rw-r--r--railties/Rakefile8
-rw-r--r--railties/guides/source/configuring.textile18
-rw-r--r--railties/lib/rails/application/routes_reloader.rb2
-rw-r--r--railties/lib/rails/commands/server.rb5
-rw-r--r--railties/lib/rails/engine.rb9
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb2
-rw-r--r--railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb12
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt13
-rw-r--r--railties/lib/rails/generators/rails/resource/resource_generator.rb1
-rw-r--r--railties/lib/rails/tasks/documentation.rake69
-rw-r--r--railties/lib/rails/test_help.rb2
-rw-r--r--railties/test/rails_info_controller_test.rb4
-rwxr-xr-xtools/console7
146 files changed, 1042 insertions, 436 deletions
diff --git a/.gitignore b/.gitignore
index 9d68f4860f..16bffc157b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,7 +15,6 @@ activesupport/test/fixtures/isolation_test
railties/test/500.html
railties/test/fixtures/tmp
railties/test/initializer/root/log
-railties/doc/guides/html/images
-railties/doc/guides/html/stylesheets
+railties/doc
railties/guides/output
railties/tmp
diff --git a/Gemfile b/Gemfile
index ea9842c0c5..7c6720ac7f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -11,6 +11,8 @@ group :mri do
if RUBY_VERSION < '1.9'
gem "system_timer"
gem "ruby-debug", ">= 0.10.3"
+ elsif RUBY_VERSION < '1.9.2'
+ gem "ruby-debug19"
end
end
diff --git a/Rakefile b/Rakefile
index 66a65fb249..2fa1f756d9 100644
--- a/Rakefile
+++ b/Rakefile
@@ -72,8 +72,8 @@ Rake::RDocTask.new do |rdoc|
rdoc.rdoc_files.include('railties/CHANGELOG')
rdoc.rdoc_files.include('railties/MIT-LICENSE')
rdoc.rdoc_files.include('railties/README')
- rdoc.rdoc_files.include('railties/lib/{*.rb,commands/*.rb,rails/*.rb,generators/*.rb}')
- rdoc.rdoc_files.exclude('railties/lib/vendor/*')
+ rdoc.rdoc_files.include('railties/lib/**/*.rb')
+ rdoc.rdoc_files.exclude('railties/lib/rails/generators/**/templates/*')
rdoc.rdoc_files.include('activerecord/README')
rdoc.rdoc_files.include('activerecord/CHANGELOG')
@@ -88,6 +88,7 @@ Rake::RDocTask.new do |rdoc|
rdoc.rdoc_files.include('actionpack/README')
rdoc.rdoc_files.include('actionpack/CHANGELOG')
rdoc.rdoc_files.include('actionpack/lib/action_controller/**/*.rb')
+ rdoc.rdoc_files.include('actionpack/lib/action_dispatch/**/*.rb')
rdoc.rdoc_files.include('actionpack/lib/action_view/**/*.rb')
rdoc.rdoc_files.exclude('actionpack/lib/action_controller/vendor/*')
diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec
index a7a2599105..410df0e106 100644
--- a/actionmailer/actionmailer.gemspec
+++ b/actionmailer/actionmailer.gemspec
@@ -20,6 +20,6 @@ Gem::Specification.new do |s|
s.has_rdoc = true
s.add_dependency('actionpack', version)
- s.add_dependency('mail', '~> 2.1.3')
+ s.add_dependency('mail', '~> 2.1.5.3')
s.add_dependency('text-format', '~> 1.0.0')
end
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 0519783d02..af7255ae4f 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -2,6 +2,7 @@ require 'mail'
require 'action_mailer/tmail_compat'
require 'action_mailer/collector'
require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/object/blank'
module ActionMailer #:nodoc:
# Action Mailer allows you to send email from your application using a mailer model and views.
@@ -290,7 +291,7 @@ module ActionMailer #:nodoc:
:parts_order => [ "text/plain", "text/enriched", "text/html" ]
}.freeze
- ActionMailer.run_base_hooks(self)
+ ActiveSupport.run_load_hooks(:action_mailer, self)
class << self
diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb
index c7f341d46c..7c59a8ae50 100644
--- a/actionmailer/lib/action_mailer/old_api.rb
+++ b/actionmailer/lib/action_mailer/old_api.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/object/try'
+require 'active_support/core_ext/object/blank'
module ActionMailer
module OldApi #:nodoc:
diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb
index 2703367fdb..882e078d1b 100644
--- a/actionmailer/lib/action_mailer/railtie.rb
+++ b/actionmailer/lib/action_mailer/railtie.rb
@@ -6,18 +6,18 @@ module ActionMailer
config.action_mailer = ActiveSupport::OrderedOptions.new
initializer "action_mailer.url_for", :before => :load_environment_config do |app|
- ActionMailer.base_hook { include app.routes.url_helpers }
+ ActiveSupport.on_load(:action_mailer) { include app.routes.url_helpers }
end
require "action_mailer/railties/log_subscriber"
log_subscriber :action_mailer, ActionMailer::Railties::LogSubscriber.new
initializer "action_mailer.logger" do
- ActionMailer.base_hook { self.logger ||= Rails.logger }
+ ActiveSupport.on_load(:action_mailer) { self.logger ||= Rails.logger }
end
initializer "action_mailer.set_configs" do |app|
- ActionMailer.base_hook do
+ ActiveSupport.on_load(:action_mailer) do
app.config.action_mailer.each do |k,v|
send "#{k}=", v
end
diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb
index 6f274c11df..baeee542be 100644
--- a/actionmailer/test/base_test.rb
+++ b/actionmailer/test/base_test.rb
@@ -39,8 +39,15 @@ class BaseTest < ActiveSupport::TestCase
end
def attachment_with_hash
- attachments['invoice.jpg'] = { :data => "you smiling", :mime_type => "image/x-jpg",
- :transfer_encoding => "base64" }
+ attachments['invoice.jpg'] = { :data => "\312\213\254\232)b",
+ :mime_type => "image/x-jpg",
+ :transfer_encoding => "base64" }
+ mail
+ end
+
+ def attachment_with_hash_default_encoding
+ attachments['invoice.jpg'] = { :data => "\312\213\254\232)b",
+ :mime_type => "image/x-jpg" }
mail
end
@@ -135,13 +142,13 @@ class BaseTest < ActiveSupport::TestCase
:mime_version => '2.0',
:reply_to => 'reply-to@test.lindsaar.net',
:date => @time)
- assert_equal(['bcc@test.lindsaar.net'], email.bcc)
- assert_equal(['cc@test.lindsaar.net'], email.cc)
- assert_equal('multipart/mixed', email.content_type)
- assert_equal('iso-8559-1', email.charset)
- assert_equal('2.0', email.mime_version)
- assert_equal(['reply-to@test.lindsaar.net'], email.reply_to)
- assert_equal(@time, email.date)
+ assert_equal(['bcc@test.lindsaar.net'], email.bcc)
+ assert_equal(['cc@test.lindsaar.net'], email.cc)
+ assert_equal('multipart/mixed; charset=iso-8559-1', email.content_type)
+ assert_equal('iso-8559-1', email.charset)
+ assert_equal('2.0', email.mime_version)
+ assert_equal(['reply-to@test.lindsaar.net'], email.reply_to)
+ assert_equal(@time, email.date)
end
test "mail() renders the template using the method being processed" do
@@ -206,6 +213,15 @@ class BaseTest < ActiveSupport::TestCase
assert_equal expected, email.attachments['invoice.jpg'].decoded
end
+ test "attachment with hash using default mail encoding" do
+ email = BaseMailer.attachment_with_hash_default_encoding
+ assert_equal(1, email.attachments.length)
+ assert_equal('invoice.jpg', email.attachments[0].filename)
+ expected = "\312\213\254\232)b"
+ expected.force_encoding(Encoding::BINARY) if '1.9'.respond_to?(:force_encoding)
+ assert_equal expected, email.attachments['invoice.jpg'].decoded
+ end
+
test "sets mime type to multipart/mixed when attachment is included" do
email = BaseMailer.attachment_with_content
assert_equal(1, email.attachments.length)
diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb
index e49307bfda..9eb067554f 100644
--- a/actionmailer/test/old_base/mail_service_test.rb
+++ b/actionmailer/test/old_base/mail_service_test.rb
@@ -784,7 +784,7 @@ EOF
expected.date = Time.local 2004, 12, 12
created = TestMailer.utf8_body @recipient
- assert_match(/åœö blah/, created.encoded)
+ assert_match(/åœö blah/, created.decoded)
end
def test_multiple_utf8_recipients
@@ -1019,8 +1019,8 @@ EOF
def test_empty_header_values_omitted
result = TestMailer.unnamed_attachment(@recipient).encoded
- assert_match %r{Content-Type: application/octet-stream;}, result
- assert_match %r{Content-Disposition: attachment;}, result
+ assert_match %r{Content-Type: application/octet-stream}, result
+ assert_match %r{Content-Disposition: attachment}, result
end
def test_headers_with_nonalpha_chars
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 5797282b41..46a175d2fa 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -64,8 +64,7 @@ module ActionController
filter
end
- ActionController.run_base_hooks(self)
-
+ ActiveSupport.run_load_hooks(:action_controller, self)
end
end
diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb
index bbde570ca9..2fd60aacc7 100644
--- a/actionpack/lib/action_controller/deprecated/base.rb
+++ b/actionpack/lib/action_controller/deprecated/base.rb
@@ -66,6 +66,18 @@ module ActionController
Rails.application.config.action_dispatch.ip_spoofing_check
end
+ def cookie_verifier_secret=(value)
+ ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret= is deprecated. " <<
+ "Please configure it on your application with config.cookie_secret=", caller
+ ActionController::Base.config.secret = value
+ end
+
+ def cookie_verifier_secret
+ ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret is deprecated. " <<
+ "Please use ActionController::Base.config.secret instead.", caller
+ ActionController::Base.config.secret
+ end
+
def trusted_proxies=(value)
ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " <<
"Please configure it on your application with config.action_dispatch.trusted_proxies=", caller
diff --git a/actionpack/lib/action_controller/metal/cookies.rb b/actionpack/lib/action_controller/metal/cookies.rb
index 7aa687b52c..75e5d40a63 100644
--- a/actionpack/lib/action_controller/metal/cookies.rb
+++ b/actionpack/lib/action_controller/metal/cookies.rb
@@ -6,7 +6,6 @@ module ActionController #:nodoc:
included do
helper_method :cookies
- cattr_accessor :cookie_verifier_secret
end
private
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 6ec788f302..424828f7e8 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -1,4 +1,5 @@
require 'active_support/base64'
+require 'active_support/core_ext/object/blank'
module ActionController
module HttpAuthentication
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index d906e1fb5b..aebd71e867 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/object/blank'
module ActionController
def self.add_renderer(key, &block)
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index 0ec89928af..29d8523ee1 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -41,7 +41,7 @@ module ActionController
log_subscriber :action_controller, ActionController::Railties::LogSubscriber.new
initializer "action_controller.logger" do
- ActionController.base_hook { self.logger ||= Rails.logger }
+ ActiveSupport.on_load(:action_controller) { self.logger ||= Rails.logger }
end
initializer "action_controller.set_configs" do |app|
@@ -53,23 +53,23 @@ module ActionController
ac.stylesheets_dir = paths.public.stylesheets.to_a.first
ac.secret = app.config.cookie_secret
- ActionController.base_hook do
+ ActiveSupport.on_load(:action_controller) do
self.config.merge!(ac)
end
end
initializer "action_controller.initialize_framework_caches" do
- ActionController.base_hook { self.cache_store ||= RAILS_CACHE }
+ ActiveSupport.on_load(:action_controller) { self.cache_store ||= RAILS_CACHE }
end
initializer "action_controller.set_helpers_path" do |app|
- ActionController.base_hook do
+ ActiveSupport.on_load(:action_controller) do
self.helpers_path = app.config.paths.app.helpers.to_a
end
end
initializer "action_controller.url_helpers" do |app|
- ActionController.base_hook do
+ ActiveSupport.on_load(:action_controller) do
extend ::ActionController::Railties::UrlHelpers.with(app.routes)
end
diff --git a/actionpack/lib/action_controller/railties/log_subscriber.rb b/actionpack/lib/action_controller/railties/log_subscriber.rb
index c2299d0b05..00ac3bdf67 100644
--- a/actionpack/lib/action_controller/railties/log_subscriber.rb
+++ b/actionpack/lib/action_controller/railties/log_subscriber.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActionController
module Railties
class LogSubscriber < Rails::LogSubscriber
diff --git a/actionpack/lib/action_controller/railties/url_helpers.rb b/actionpack/lib/action_controller/railties/url_helpers.rb
index 5f95e1c621..9df5665542 100644
--- a/actionpack/lib/action_controller/railties/url_helpers.rb
+++ b/actionpack/lib/action_controller/railties/url_helpers.rb
@@ -1,14 +1,14 @@
module ActionController
module Railties
module UrlHelpers
- def self.with(router)
+ def self.with(routes)
Module.new do
define_method(:inherited) do |klass|
super(klass)
- klass.send(:include, router.url_helpers)
+ klass.send(:include, routes.url_helpers)
end
end
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb
index 3f966b1b64..7fdaffe3eb 100644
--- a/actionpack/lib/action_controller/record_identifier.rb
+++ b/actionpack/lib/action_controller/record_identifier.rb
@@ -76,8 +76,8 @@ module ActionController
# method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to
# make sure yourself that your dom ids are valid, in case you overwrite this method.
def record_key_for_dom_id(record)
- return record.id unless record.respond_to?(:to_model)
- key = record.to_model.to_key
+ record = record.to_model if record.respond_to?(:to_model)
+ key = record.to_key
key ? sanitize_dom_id(key.join('_')) : key
end
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 120f34460e..2d4cf2fafb 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -1,4 +1,5 @@
require 'rack/session/abstract/id'
+require 'active_support/core_ext/object/blank'
module ActionController
module TemplateAssertions
@@ -117,9 +118,9 @@ module ActionController
end
end
- def assign_parameters(router, controller_path, action, parameters = {})
+ def assign_parameters(routes, controller_path, action, parameters = {})
parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
- extra_keys = router.extra_keys(parameters)
+ extra_keys = routes.extra_keys(parameters)
non_path_parameters = get? ? query_parameters : request_parameters
parameters.each do |key, value|
if value.is_a? Fixnum
@@ -321,7 +322,7 @@ module ActionController
def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
# Sanity check for required instance variables so we can give an
# understandable error message.
- %w(@router @controller @request @response).each do |iv_name|
+ %w(@routes @controller @request @response).each do |iv_name|
if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
raise "#{iv_name} is nil: make sure you set it in your test's setup method."
end
@@ -337,7 +338,7 @@ module ActionController
@request.env['REQUEST_METHOD'] = http_method
parameters ||= {}
- @request.assign_parameters(@router, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
+ @request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
@request.session = ActionController::TestSession.new(session) unless session.nil?
@request.session["flash"] = @request.flash.update(flash || {})
@@ -446,7 +447,7 @@ module ActionController
:relative_url_root => nil,
:_path_segments => @request.symbolized_path_parameters)
- url, query_string = @router.url_for(options).split("?", 2)
+ url, query_string = @routes.url_for(options).split("?", 2)
@request.env["SCRIPT_NAME"] = @controller.config.relative_url_root
@request.env["PATH_INFO"] = url
diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb
index d2404e63c5..9b9e81440b 100644
--- a/actionpack/lib/action_dispatch/http/cache.rb
+++ b/actionpack/lib/action_dispatch/http/cache.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActionDispatch
module Http
module Cache
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
index e42b4d09b0..152aaa2e67 100644
--- a/actionpack/lib/action_dispatch/http/filter_parameters.rb
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/object/duplicable'
module ActionDispatch
module Http
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index fec250e928..be89924015 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -5,7 +5,7 @@ module ActionDispatch
#
# For backward compatibility, the post \format is extracted from the
# X-Post-Data-Format HTTP header if present.
- def content_type
+ def content_mime_type
@env["action_dispatch.request.content_type"] ||= begin
if @env['CONTENT_TYPE'] =~ /^([^,\;]*)/
Mime::Type.lookup($1.strip.downcase)
@@ -15,13 +15,17 @@ module ActionDispatch
end
end
+ def content_type
+ content_mime_type && content_mime_type.to_s
+ end
+
# Returns the accepted MIME type for the request.
def accepts
@env["action_dispatch.request.accepts"] ||= begin
header = @env['HTTP_ACCEPT'].to_s.strip
if header.empty?
- [content_type]
+ [content_mime_type]
else
Mime::Type.parse(header)
end
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index 3f1a77295d..d6a805bf3b 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -1,5 +1,6 @@
require 'set'
require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/object/blank'
module Mime
class Mimes < Array
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index ea9f0f99c2..8b8426b5aa 100755
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -96,11 +96,11 @@ module ActionDispatch
end
def forgery_whitelisted?
- method == :get || xhr? || content_type.nil? || !content_type.verify_request?
+ method == :get || xhr? || content_mime_type.nil? || !content_mime_type.verify_request?
end
def media_type
- content_type.to_s
+ content_mime_type.to_s
end
# Returns the content length of the request as an integer.
@@ -157,7 +157,7 @@ module ActionDispatch
end
def form_data?
- FORM_DATA_MEDIA_TYPES.include?(content_type.to_s)
+ FORM_DATA_MEDIA_TYPES.include?(content_mime_type.to_s)
end
def body_stream #:nodoc:
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index 9cfe5a5ea9..362e5ec970 100644
--- a/actionpack/lib/action_dispatch/http/response.rb
+++ b/actionpack/lib/action_dispatch/http/response.rb
@@ -1,5 +1,6 @@
require 'digest/md5'
require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/object/blank'
module ActionDispatch # :nodoc:
# Represents an HTTP response generated by a controller action. One can use
diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb
index dc6121b911..81d2517304 100644
--- a/actionpack/lib/action_dispatch/http/upload.rb
+++ b/actionpack/lib/action_dispatch/http/upload.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActionDispatch
module Http
module UploadedFile
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index ab7130ab08..cb0d12cab1 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -168,12 +168,12 @@ module ActionDispatch
class SignedCookieJar < CookieJar #:nodoc:
def initialize(parent_jar)
- unless ActionController::Base.cookie_verifier_secret
- raise "You must set ActionController::Base.cookie_verifier_secret to use signed cookies"
+ unless ActionController::Base.config.secret
+ raise "You must set ActionController::Base.config.secret"
end
@parent_jar = parent_jar
- @verifier = ActiveSupport::MessageVerifier.new(ActionController::Base.cookie_verifier_secret)
+ @verifier = ActiveSupport::MessageVerifier.new(ActionController::Base.config.secret)
end
def [](name)
diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb
index f4c4324fb0..18a3688bb0 100644
--- a/actionpack/lib/action_dispatch/middleware/params_parser.rb
+++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb
@@ -25,7 +25,9 @@ module ActionDispatch
return false if request.content_length.zero?
- mime_type = content_type_from_legacy_post_data_format_header(env) || request.content_type
+ mime_type = content_type_from_legacy_post_data_format_header(env) ||
+ request.content_mime_type
+
strategy = @parsers[mime_type]
return false unless strategy
@@ -53,7 +55,7 @@ module ActionDispatch
raise
{ "body" => request.raw_post,
- "content_type" => request.content_type,
+ "content_type" => request.content_mime_type,
"content_length" => request.content_length,
"exception" => "#{e.message} (#{e.class})",
"backtrace" => e.backtrace }
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index 311880cabc..dddedc832f 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -1,5 +1,6 @@
require 'rack/utils'
require 'rack/request'
+require 'active_support/core_ext/object/blank'
module ActionDispatch
module Session
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 22da82479e..3331b7c25e 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/object/blank'
module ActionDispatch
module Session
diff --git a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
index 58beaf4824..e8c2e74314 100644
--- a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActionDispatch
module Routing
class RouteSet
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 39260f7ff9..74d0297898 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/object/blank'
module ActionDispatch
module Routing
@@ -258,6 +259,7 @@ module ActionDispatch
def scope(*args)
options = args.extract_options!
+ options = options.dup
case args.first
when String
@@ -423,8 +425,13 @@ module ActionDispatch
singular
end
+ # Checks for uncountable plurals, and appends "_index" if they're.
def collection_name
- plural
+ uncountable? ? "#{plural}_index" : plural
+ end
+
+ def uncountable?
+ singular == plural
end
def name_for_action(action)
@@ -439,6 +446,32 @@ module ActionDispatch
def id_segment
":#{singular}_id"
end
+
+ def constraints
+ options[:constraints] || {}
+ end
+
+ def id_constraint?
+ options[:id] && options[:id].is_a?(Regexp) || constraints[:id] && constraints[:id].is_a?(Regexp)
+ end
+
+ def id_constraint
+ options[:id] || constraints[:id]
+ end
+
+ def collection_options
+ (options || {}).dup.tap do |options|
+ options.delete(:id)
+ options[:constraints] = options[:constraints].dup if options[:constraints]
+ options[:constraints].delete(:id) if options[:constraints].is_a?(Hash)
+ end
+ end
+
+ def nested_options
+ options = { :name_prefix => member_name }
+ options["#{singular}_id".to_sym] = id_constraint if id_constraint?
+ options
+ end
end
class SingletonResource < Resource #:nodoc:
@@ -483,12 +516,14 @@ module ActionDispatch
yield if block_given?
end
- get :show if resource.actions.include?(:show)
- post :create if resource.actions.include?(:create)
- put :update if resource.actions.include?(:update)
- delete :destroy if resource.actions.include?(:destroy)
- get :new, :as => resource.name if resource.actions.include?(:new)
- get :edit, :as => resource.name if resource.actions.include?(:edit)
+ scope(resource.options) do
+ get :show if resource.actions.include?(:show)
+ post :create if resource.actions.include?(:create)
+ put :update if resource.actions.include?(:update)
+ delete :destroy if resource.actions.include?(:destroy)
+ get :new, :as => resource.name if resource.actions.include?(:new)
+ get :edit, :as => resource.name if resource.actions.include?(:edit)
+ end
end
end
@@ -509,17 +544,21 @@ module ActionDispatch
yield if block_given?
with_scope_level(:collection) do
- get :index if resource.actions.include?(:index)
- post :create if resource.actions.include?(:create)
- get :new, :as => resource.singular if resource.actions.include?(:new)
+ scope(resource.collection_options) do
+ get :index if resource.actions.include?(:index)
+ post :create if resource.actions.include?(:create)
+ get :new, :as => resource.singular if resource.actions.include?(:new)
+ end
end
with_scope_level(:member) do
scope(':id') do
- get :show if resource.actions.include?(:show)
- put :update if resource.actions.include?(:update)
- delete :destroy if resource.actions.include?(:destroy)
- get :edit, :as => resource.singular if resource.actions.include?(:edit)
+ scope(resource.options) do
+ get :show if resource.actions.include?(:show)
+ put :update if resource.actions.include?(:update)
+ delete :destroy if resource.actions.include?(:destroy)
+ get :edit, :as => resource.singular if resource.actions.include?(:edit)
+ end
end
end
end
@@ -558,7 +597,7 @@ module ActionDispatch
end
with_scope_level(:nested) do
- scope(parent_resource.id_segment, :name_prefix => parent_resource.member_name) do
+ scope(parent_resource.id_segment, parent_resource.nested_options) do
yield
end
end
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index 1bb81ede3b..b7e9b0c95a 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -80,7 +80,7 @@ module ActionDispatch
expected_path = "/#{expected_path}" unless expected_path[0] == ?/
# Load routes.rb if it hasn't been loaded.
- generated_path, extra_keys = @router.generate_extras(options, defaults)
+ generated_path, extra_keys = @routes.generate_extras(options, defaults)
found_extras = options.reject {|k, v| ! extra_keys.include? k}
msg = build_message(message, "found extras <?>, not <?>", found_extras, extras)
@@ -125,7 +125,7 @@ module ActionDispatch
end
# A helper to make it easier to test different route configurations.
- # This method temporarily replaces @router
+ # This method temporarily replaces @routes
# with a new RouteSet instance.
#
# The new instance is yielded to the passed block. Typically the block
@@ -142,9 +142,9 @@ module ActionDispatch
# end
#
def with_routing
- old_routes, @router = @router, ActionDispatch::Routing::RouteSet.new
+ old_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new
old_controller, @controller = @controller, @controller.clone if @controller
- _router = @router
+ _routes = @routes
# Unfortunately, there is currently an abstraction leak between AC::Base
# and AV::Base which requires having the URL helpers in both AC and AV.
@@ -153,14 +153,14 @@ module ActionDispatch
#
# TODO: Make this unnecessary
if @controller
- @controller.singleton_class.send(:include, _router.url_helpers)
+ @controller.singleton_class.send(:include, _routes.url_helpers)
@controller.view_context_class = Class.new(@controller.view_context_class) do
- include _router.url_helpers
+ include _routes.url_helpers
end
end
- yield @router
+ yield @routes
ensure
- @router = old_routes
+ @routes = old_routes
if @controller
@controller = old_controller
end
@@ -168,7 +168,7 @@ module ActionDispatch
# ROUTES TODO: These assertions should really work in an integration context
def method_missing(selector, *args, &block)
- if @controller && @router.named_routes.helpers.include?(selector)
+ if @controller && @routes && @routes.named_routes.helpers.include?(selector)
@controller.send(selector, *args, &block)
else
super
@@ -185,7 +185,7 @@ module ActionDispatch
request.env["REQUEST_METHOD"] = request_method.to_s.upcase if request_method
request.path = path
- params = @router.recognize_path(path, { :method => request.method })
+ params = @routes.recognize_path(path, { :method => request.method })
request.path_parameters = params.with_indifferent_access
request
diff --git a/actionpack/lib/action_dispatch/testing/performance_test.rb b/actionpack/lib/action_dispatch/testing/performance_test.rb
index 1b9a6c18b7..33a5c68b9d 100644
--- a/actionpack/lib/action_dispatch/testing/performance_test.rb
+++ b/actionpack/lib/action_dispatch/testing/performance_test.rb
@@ -1,7 +1,7 @@
require 'active_support/testing/performance'
require 'active_support/testing/default'
-if defined?(ActiveSupport::Testing::Performance)
+begin
module ActionDispatch
# An integration test that runs a code profiler on your test methods.
# Profiling output for combinations of each test method, measurement, and
@@ -14,4 +14,6 @@ if defined?(ActiveSupport::Testing::Performance)
include ActiveSupport::Testing::Default
end
end
+rescue NameError
+ $stderr.puts "Specify ruby-prof as application's dependency in Gemfile to run benchmarks."
end \ No newline at end of file
diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb
index 20288aa7a5..090e03cf44 100644
--- a/actionpack/lib/action_dispatch/testing/test_request.rb
+++ b/actionpack/lib/action_dispatch/testing/test_request.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActionDispatch
class TestRequest < Request
DEFAULT_ENV = Rack::MockRequest.env_for('/')
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 919b1e3470..a9b0715b2e 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -173,7 +173,7 @@ module ActionView #:nodoc:
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
end
- ActionView.run_base_hooks(self)
+ ActiveSupport.run_load_hooks(:action_view, self)
attr_accessor :base_path, :assigns, :template_extension, :lookup_context
attr_internal :captures, :request, :controller, :template, :config
diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb
index 80b3d3a664..44e193f18e 100644
--- a/actionpack/lib/action_view/helpers/active_model_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_model_helper.rb
@@ -6,7 +6,7 @@ require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/object/blank'
module ActionView
- ActionView.base_hook do
+ ActiveSupport.on_load(:action_view) do
class ActionView::Base
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>".html_safe }
cattr_accessor :field_error_proc
@@ -97,10 +97,10 @@ module ActionView
end
# Returns a string containing the error message attached to the +method+ on the +object+ if one exists.
- # This error message is wrapped in a <tt>DIV</tt> tag, which can be extended to include a <tt>:prepend_text</tt>
- # and/or <tt>:append_text</tt> (to properly explain the error), and a <tt>:css_class</tt> to style it
- # accordingly. +object+ should either be the name of an instance variable or the actual object. The method can be
- # passed in either as a string or a symbol.
+ # This error message is wrapped in a <tt>DIV</tt> tag by default or with <tt>:html_tag</tt> if specified,
+ # which can be extended to include a <tt>:prepend_text</tt> and/or <tt>:append_text</tt> (to properly explain
+ # the error), and a <tt>:css_class</tt> to style it accordingly. +object+ should either be the name of an
+ # instance variable or the actual object. The method can be passed in either as a string or a symbol.
# As an example, let's say you have a model <tt>@post</tt> that has an error message on the +title+ attribute:
#
# <%= error_message_on "post", "title" %>
@@ -112,25 +112,28 @@ module ActionView
# <%= error_message_on "post", "title",
# :prepend_text => "Title simply ",
# :append_text => " (or it won't work).",
+ # :html_tag => "span",
# :css_class => "inputError" %>
+ # # => <span class="inputError">Title simply can't be empty (or it won't work).</span>
def error_message_on(object, method, *args)
options = args.extract_options!
unless args.empty?
ActiveSupport::Deprecation.warn('error_message_on takes an option hash instead of separate ' +
- 'prepend_text, append_text, and css_class arguments', caller)
+ 'prepend_text, append_text, html_tag, and css_class arguments', caller)
options[:prepend_text] = args[0] || ''
options[:append_text] = args[1] || ''
- options[:css_class] = args[2] || 'formError'
+ options[:html_tag] = args[2] || 'div'
+ options[:css_class] = args[3] || 'formError'
end
- options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError')
+ options.reverse_merge!(:prepend_text => '', :append_text => '', :html_tag => 'div', :css_class => 'formError')
object = convert_to_model(object)
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
(errors = obj.errors[method]).presence
- content_tag("div",
- "#{options[:prepend_text]}#{ERB::Util.h(errors.first)}#{options[:append_text]}".html_safe,
+ content_tag(options[:html_tag],
+ (options[:prepend_text].html_safe << errors.first).safe_concat(options[:append_text]),
:class => options[:css_class]
)
else
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 02ad41719b..e4ec17467e 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -108,7 +108,7 @@ module ActionView
# "http://asset%d.example.com", "https://asset1.example.com"
# )
#
- # === Using asset timestamps
+ # === Customizing the asset path
#
# By default, Rails appends asset's timestamps to all asset paths. This allows
# you to set a cache-expiration date for the asset far into the future, but
@@ -133,6 +133,65 @@ module ActionView
# will request the same assets over and over again even thought they didn't
# change. You can use something like Live HTTP Headers for Firefox to verify
# that the cache is indeed working.
+ #
+ # This strategy works well enough for most server setups and requires the
+ # least configuration, but if you deploy several application servers at
+ # different times - say to handle a temporary spike in load - then the
+ # asset time stamps will be out of sync. In a setup like this you may want
+ # to set the way that asset paths are generated yourself.
+ #
+ # Altering the asset paths that Rails generates can be done in two ways.
+ # The easiest is to define the RAILS_ASSET_ID environment variable. The
+ # contents of this variable will always be used in preference to
+ # calculated timestamps. A more complex but flexible way is to set
+ # <tt>ActionController::Base.config.asset_path</tt> to a proc
+ # that takes the unmodified asset path and returns the path needed for
+ # your asset caching to work. Typically you'd do something like this in
+ # <tt>config/environments/production.rb</tt>:
+ #
+ # # Normally you'd calculate RELEASE_NUMBER at startup.
+ # RELEASE_NUMBER = 12345
+ # config.action_controller.asset_path_template = proc { |asset_path|
+ # "/release-#{RELEASE_NUMBER}#{asset_path}"
+ # }
+ #
+ # This example would cause the following behaviour on all servers no
+ # matter when they were deployed:
+ #
+ # image_tag("rails.png")
+ # # => <img alt="Rails" src="/release-12345/images/rails.png" />
+ # stylesheet_link_tag("application")
+ # # => <link href="/release-12345/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
+ #
+ # Changing the asset_path does require that your web servers have
+ # knowledge of the asset template paths that you rewrite to so it's not
+ # suitable for out-of-the-box use. To use the example given above you
+ # could use something like this in your Apache VirtualHost configuration:
+ #
+ # <LocationMatch "^/release-\d+/(images|javascripts|stylesheets)/.*$">
+ # # Some browsers still send conditional-GET requests if there's a
+ # # Last-Modified header or an ETag header even if they haven't
+ # # reached the expiry date sent in the Expires header.
+ # Header unset Last-Modified
+ # Header unset ETag
+ # FileETag None
+ #
+ # # Assets requested using a cache-busting filename should be served
+ # # only once and then cached for a really long time. The HTTP/1.1
+ # # spec frowns on hugely-long expiration times though and suggests
+ # # that assets which never expire be served with an expiration date
+ # # 1 year from access.
+ # ExpiresActive On
+ # ExpiresDefault "access plus 1 year"
+ # </LocationMatch>
+ #
+ # # We use cached-busting location names with the far-future expires
+ # # headers to ensure that if a file does change it can force a new
+ # # request. The actual asset filenames are still the same though so we
+ # # need to rewrite the location from the cache-busting location to the
+ # # real asset location so that we can serve it.
+ # RewriteEngine On
+ # RewriteRule ^/release-\d+/(images|javascripts|stylesheets)/(.*)$ /$1/$2 [L]
module AssetTagHelper
JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls', 'rails'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)
@@ -646,7 +705,7 @@ module ActionView
source += ".#{ext}" if rewrite_extension?(source, dir, ext)
source = "/#{dir}/#{source}" unless source[0] == ?/
- source = rewrite_asset_path(source)
+ source = rewrite_asset_path(source, config.asset_path)
has_request = controller.respond_to?(:request)
if has_request && include_host && source !~ %r{^#{controller.config.relative_url_root}/}
@@ -710,7 +769,13 @@ module ActionView
# Break out the asset path rewrite in case plugins wish to put the asset id
# someplace other than the query string.
- def rewrite_asset_path(source)
+ def rewrite_asset_path(source, path = nil)
+ if path && path.respond_to?(:call)
+ return path.call(source)
+ elsif path && path.is_a?(String)
+ return path % [source]
+ end
+
asset_id = rails_asset_id(source)
if asset_id.blank?
source
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index f0be814700..20598237e9 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActionView
module Helpers
# CaptureHelper exposes methods to let you extract generated markup which
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 2ba5339b7d..89560d0b49 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -4,6 +4,7 @@ require 'action_view/helpers/tag_helper'
require 'action_view/helpers/form_tag_helper'
require 'active_support/core_ext/class/inheritable_attributes'
require 'active_support/core_ext/hash/slice'
+require 'active_support/core_ext/object/blank'
module ActionView
module Helpers
@@ -1220,7 +1221,7 @@ module ActionView
end
end
- ActionView.base_hook do
+ ActiveSupport.on_load(:action_view) do
class ActionView::Base
cattr_accessor :default_form_builder
@@default_form_builder = ::ActionView::Helpers::FormBuilder
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 4c523d4b20..11c6351bd3 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -1,6 +1,7 @@
require 'cgi'
require 'erb'
require 'action_view/helpers/form_helper'
+require 'active_support/core_ext/object/blank'
module ActionView
module Helpers
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 07694f5ebb..ca100e102e 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -1,6 +1,7 @@
require 'cgi'
require 'action_view/helpers/tag_helper'
require 'active_support/core_ext/object/returning'
+require 'active_support/core_ext/object/blank'
module ActionView
module Helpers
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index 719b64b940..605e5d5873 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/core_ext/float/rounding'
+require 'active_support/core_ext/object/blank'
module ActionView
module Helpers #:nodoc:
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index ccdc8181db..ebe0b4e876 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -1,6 +1,7 @@
require 'set'
require 'active_support/json'
require 'active_support/core_ext/object/returning'
+require 'active_support/core_ext/object/blank'
module ActionView
module Helpers
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index 9b4cacd4d7..c09d01eeee 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/object/blank'
require 'set'
module ActionView
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 27be1690dd..0e1bc139ff 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/object/blank'
require 'action_view/helpers/tag_helper'
module ActionView
diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb
index 9cf007cd2b..c606a71e18 100644
--- a/actionpack/lib/action_view/railtie.rb
+++ b/actionpack/lib/action_view/railtie.rb
@@ -10,14 +10,14 @@ module ActionView
initializer "action_view.cache_asset_timestamps" do |app|
unless app.config.cache_classes
- ActionView.base_hook do
+ ActiveSupport.on_load(:action_view) do
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
end
end
end
initializer "action_view.set_configs" do |app|
- ActionView.base_hook do
+ ActiveSupport.on_load(:action_view) do
app.config.action_view.each do |k,v|
send "#{k}=", v
end
diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb
index 17d16556b9..f04a89c1ac 100644
--- a/actionpack/lib/action_view/render/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActionView
# There's also a convenience method for rendering sub templates within the current controller that depends on a
# single object (we call this kind of sub templates for partials). It relies on the fact that partials should
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 8e8afaa43f..a223b3a55f 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -35,12 +35,7 @@ module ActionView
def cached(key, prefix, name, partial)
return yield unless key && caching?
- scope = @cached[key][prefix][name]
- if scope.key?(partial)
- scope[partial]
- else
- scope[partial] = yield
- end
+ @cached[key][prefix][name][partial] ||= yield
end
end
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index b0ababe344..23b0c6e121 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/object/blank'
require 'action_controller/test_case'
require 'action_view'
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index 5b2ff3e871..143491a640 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -95,7 +95,7 @@ module ActiveSupport
map.connect ':controller/:action/:id'
end
- ActionController::IntegrationTest.app.router.draw do |map|
+ ActionController::IntegrationTest.app.routes.draw do |map|
# FIXME: match ':controller(/:action(/:id))'
map.connect ':controller/:action/:id'
end
@@ -104,12 +104,11 @@ module ActiveSupport
end
class RoutedRackApp
- attr_reader :router
- alias routes router
+ attr_reader :routes
- def initialize(router, &blk)
- @router = router
- @stack = ActionDispatch::MiddlewareStack.new(&blk).build(@router)
+ def initialize(routes, &blk)
+ @routes = routes
+ @stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
end
def call(env)
@@ -234,7 +233,7 @@ module ActionView
# Must repeat the setup because AV::TestCase is a duplication
# of AC::TestCase
setup do
- @router = SharedTestRoutes
+ @routes = SharedTestRoutes
end
end
end
@@ -250,7 +249,7 @@ module ActionController
include ActionDispatch::TestProcess
setup do
- @router = SharedTestRoutes
+ @routes = SharedTestRoutes
end
end
end
diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb
index 5643ad5ad6..9f5e8ec657 100644
--- a/actionpack/test/activerecord/polymorphic_routes_test.rb
+++ b/actionpack/test/activerecord/polymorphic_routes_test.rb
@@ -40,12 +40,12 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
def test_with_record
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}", polymorphic_url(@project)
end
end
-
+
def test_with_class
with_test_routes do
assert_equal "http://example.com/projects", polymorphic_url(@project.class)
@@ -53,67 +53,67 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
def test_with_new_record
- with_test_routes do
+ with_test_routes do
assert_equal "http://example.com/projects", polymorphic_url(@project)
end
end
def test_with_destroyed_record
- with_test_routes do
+ with_test_routes do
@project.destroy
assert_equal "http://example.com/projects", polymorphic_url(@project)
end
end
def test_with_record_and_action
- with_test_routes do
+ with_test_routes do
assert_equal "http://example.com/projects/new", polymorphic_url(@project, :action => 'new')
end
end
def test_url_helper_prefixed_with_new
- with_test_routes do
+ with_test_routes do
assert_equal "http://example.com/projects/new", new_polymorphic_url(@project)
end
end
def test_url_helper_prefixed_with_edit
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}/edit", edit_polymorphic_url(@project)
end
end
-
+
def test_url_helper_prefixed_with_edit_with_url_options
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}/edit?param1=10", edit_polymorphic_url(@project, :param1 => '10')
end
end
-
+
def test_url_helper_with_url_options
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}?param1=10", polymorphic_url(@project, :param1 => '10')
end
end
def test_format_option
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}.pdf", polymorphic_url(@project, :format => :pdf)
end
end
-
+
def test_format_option_with_url_options
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}.pdf?param1=10", polymorphic_url(@project, :format => :pdf, :param1 => '10')
end
end
-
+
def test_id_and_format_option
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}.pdf", polymorphic_url(:id => @project, :format => :pdf)
end
@@ -126,14 +126,14 @@ class PolymorphicRoutesTest < ActionController::TestCase
assert_equal "http://example.com/projects/#{@project.id}/tasks/#{@task.id}", polymorphic_url([@project, @task])
end
end
-
+
def test_with_nested_unsaved
with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}/tasks", polymorphic_url([@project, @task])
end
end
-
+
def test_with_nested_destroyed
with_test_routes do
@project.save
@@ -141,63 +141,63 @@ class PolymorphicRoutesTest < ActionController::TestCase
assert_equal "http://example.com/projects/#{@project.id}/tasks", polymorphic_url([@project, @task])
end
end
-
+
def test_with_nested_class
with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}/tasks", polymorphic_url([@project, @task.class])
end
end
-
+
def test_class_with_array_and_namespace
- with_admin_test_routes do
+ with_admin_test_routes do
assert_equal "http://example.com/admin/projects", polymorphic_url([:admin, @project.class])
end
end
-
+
def test_new_with_array_and_namespace
- with_admin_test_routes do
+ with_admin_test_routes do
assert_equal "http://example.com/admin/projects/new", polymorphic_url([:admin, @project], :action => 'new')
end
end
-
+
def test_unsaved_with_array_and_namespace
- with_admin_test_routes do
+ with_admin_test_routes do
assert_equal "http://example.com/admin/projects", polymorphic_url([:admin, @project])
end
end
-
+
def test_nested_unsaved_with_array_and_namespace
- with_admin_test_routes do
+ with_admin_test_routes do
@project.save
assert_equal "http://example.com/admin/projects/#{@project.id}/tasks", polymorphic_url([:admin, @project, @task])
end
end
-
+
def test_nested_with_array_and_namespace
- with_admin_test_routes do
+ with_admin_test_routes do
@project.save
@task.save
assert_equal "http://example.com/admin/projects/#{@project.id}/tasks/#{@task.id}", polymorphic_url([:admin, @project, @task])
end
end
-
+
def test_ordering_of_nesting_and_namespace
- with_admin_and_site_test_routes do
+ with_admin_and_site_test_routes do
@project.save
@task.save
@step.save
assert_equal "http://example.com/admin/projects/#{@project.id}/site/tasks/#{@task.id}/steps/#{@step.id}", polymorphic_url([:admin, @project, :site, @task, @step])
end
end
-
+
def test_nesting_with_array_ending_in_singleton_resource
with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}/bid", polymorphic_url([@project, :bid])
end
end
-
+
def test_nesting_with_array_containing_singleton_resource
with_test_routes do
@project.save
@@ -205,7 +205,7 @@ class PolymorphicRoutesTest < ActionController::TestCase
assert_equal "http://example.com/projects/#{@project.id}/bid/tasks/#{@task.id}", polymorphic_url([@project, :bid, @task])
end
end
-
+
def test_nesting_with_array_containing_singleton_resource_and_format
with_test_routes do
@project.save
@@ -213,7 +213,7 @@ class PolymorphicRoutesTest < ActionController::TestCase
assert_equal "http://example.com/projects/#{@project.id}/bid/tasks/#{@task.id}.pdf", polymorphic_url([@project, :bid, @task], :format => :pdf)
end
end
-
+
def test_nesting_with_array_containing_namespace_and_singleton_resource
with_admin_test_routes do
@project.save
@@ -221,47 +221,47 @@ class PolymorphicRoutesTest < ActionController::TestCase
assert_equal "http://example.com/admin/projects/#{@project.id}/bid/tasks/#{@task.id}", polymorphic_url([:admin, @project, :bid, @task])
end
end
-
+
def test_nesting_with_array_containing_nil
with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}/bid", polymorphic_url([@project, nil, :bid])
end
end
-
+
def test_with_array_containing_single_object
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}", polymorphic_url([nil, @project])
end
end
-
+
def test_with_array_containing_single_name
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects", polymorphic_url([:projects])
end
end
-
+
def test_with_array_containing_symbols
with_test_routes do
assert_equal "http://example.com/series/new", polymorphic_url([:new, :series])
end
end
-
+
def test_with_hash
- with_test_routes do
+ with_test_routes do
@project.save
assert_equal "http://example.com/projects/#{@project.id}", polymorphic_url(:id => @project)
end
end
-
+
def test_polymorphic_path_accepts_options
- with_test_routes do
+ with_test_routes do
assert_equal "/projects/new", polymorphic_path(@project, :action => 'new')
end
end
-
+
def test_polymorphic_path_does_not_modify_arguments
with_admin_test_routes do
@project.save
@@ -275,108 +275,108 @@ class PolymorphicRoutesTest < ActionController::TestCase
assert_equal original_args, [object_array, options]
end
end
-
+
# Tests for names where .plural.singular doesn't round-trip
def test_with_irregular_plural_record
- with_test_routes do
+ with_test_routes do
@tax.save
assert_equal "http://example.com/taxes/#{@tax.id}", polymorphic_url(@tax)
end
end
-
+
def test_with_irregular_plural_class
- with_test_routes do
+ with_test_routes do
assert_equal "http://example.com/taxes", polymorphic_url(@tax.class)
end
end
-
+
def test_with_irregular_plural_new_record
- with_test_routes do
+ with_test_routes do
assert_equal "http://example.com/taxes", polymorphic_url(@tax)
end
end
def test_with_irregular_plural_destroyed_record
with_test_routes do
- @tax.destroy
+ @tax.destroy
assert_equal "http://example.com/taxes", polymorphic_url(@tax)
end
end
-
+
def test_with_irregular_plural_record_and_action
- with_test_routes do
+ with_test_routes do
assert_equal "http://example.com/taxes/new", polymorphic_url(@tax, :action => 'new')
end
end
-
+
def test_irregular_plural_url_helper_prefixed_with_new
- with_test_routes do
+ with_test_routes do
assert_equal "http://example.com/taxes/new", new_polymorphic_url(@tax)
end
end
-
+
def test_irregular_plural_url_helper_prefixed_with_edit
- with_test_routes do
+ with_test_routes do
@tax.save
assert_equal "http://example.com/taxes/#{@tax.id}/edit", edit_polymorphic_url(@tax)
end
end
-
+
def test_with_nested_irregular_plurals
- with_test_routes do
+ with_test_routes do
@tax.save
@fax.save
assert_equal "http://example.com/taxes/#{@tax.id}/faxes/#{@fax.id}", polymorphic_url([@tax, @fax])
end
end
-
+
def test_with_nested_unsaved_irregular_plurals
- with_test_routes do
+ with_test_routes do
@tax.save
assert_equal "http://example.com/taxes/#{@tax.id}/faxes", polymorphic_url([@tax, @fax])
end
end
-
+
def test_new_with_irregular_plural_array_and_namespace
- with_admin_test_routes do
+ with_admin_test_routes do
assert_equal "http://example.com/admin/taxes/new", polymorphic_url([:admin, @tax], :action => 'new')
end
end
-
+
def test_class_with_irregular_plural_array_and_namespace
- with_admin_test_routes do
+ with_admin_test_routes do
assert_equal "http://example.com/admin/taxes", polymorphic_url([:admin, @tax.class])
end
end
-
+
def test_unsaved_with_irregular_plural_array_and_namespace
- with_admin_test_routes do
+ with_admin_test_routes do
assert_equal "http://example.com/admin/taxes", polymorphic_url([:admin, @tax])
end
end
-
+
def test_nesting_with_irregular_plurals_and_array_ending_in_singleton_resource
- with_test_routes do
+ with_test_routes do
@tax.save
assert_equal "http://example.com/taxes/#{@tax.id}/bid", polymorphic_url([@tax, :bid])
end
end
-
+
def test_with_array_containing_single_irregular_plural_object
- with_test_routes do
+ with_test_routes do
@tax.save
assert_equal "http://example.com/taxes/#{@tax.id}", polymorphic_url([nil, @tax])
end
end
-
+
def test_with_array_containing_single_name_irregular_plural
- with_test_routes do
+ with_test_routes do
@tax.save
assert_equal "http://example.com/taxes", polymorphic_url([:taxes])
end
end
-
- # Tests for uncountable names
+
+ # Tests for uncountable names
def test_uncountable_resource
with_test_routes do
@series.save
@@ -400,11 +400,11 @@ class PolymorphicRoutesTest < ActionController::TestCase
map.resources :series
end
- self.class.send(:include, @router.url_helpers)
+ self.class.send(:include, @routes.url_helpers)
yield
end
end
-
+
def with_admin_test_routes(options = {})
with_routing do |set|
set.draw do |map|
@@ -422,11 +422,11 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
end
- self.class.send(:include, @router.url_helpers)
+ self.class.send(:include, @routes.url_helpers)
yield
end
end
-
+
def with_admin_and_site_test_routes(options = {})
with_routing do |set|
set.draw do |map|
@@ -441,7 +441,7 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
end
- self.class.send(:include, @router.url_helpers)
+ self.class.send(:include, @routes.url_helpers)
yield
end
end
diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb
index f0ad652d50..217260fdcd 100644
--- a/actionpack/test/controller/caching_test.rb
+++ b/actionpack/test/controller/caching_test.rb
@@ -81,9 +81,9 @@ class PageCachingTest < ActionController::TestCase
match '/', :to => 'posts#index', :as => :main
end
@params[:format] = 'rss'
- assert_equal '/posts.rss', @router.url_for(@params)
+ assert_equal '/posts.rss', @routes.url_for(@params)
@params[:format] = nil
- assert_equal '/', @router.url_for(@params)
+ assert_equal '/', @routes.url_for(@params)
end
end
@@ -518,7 +518,7 @@ class ActionCacheTest < ActionController::TestCase
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = ActionCachingTestController.new
- @controller.singleton_class.send(:include, @router.url_helpers)
+ @controller.singleton_class.send(:include, @routes.url_helpers)
@request.host = 'hostname.com'
end
diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb
index 36498d13a9..278cae1415 100644
--- a/actionpack/test/controller/cookie_test.rb
+++ b/actionpack/test/controller/cookie_test.rb
@@ -1,6 +1,6 @@
require 'abstract_unit'
-ActionController::Base.cookie_verifier_secret = "thisISverySECRET123"
+ActionController::Base.config.secret = "thisISverySECRET123"
class CookieTest < ActionController::TestCase
class TestController < ActionController::Base
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index c9782856bd..1e2ee06adc 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -430,3 +430,50 @@ class MetalIntegrationTest < ActionController::IntegrationTest
assert_equal 'http://www.example.com/foo', url_for(:controller => "foo")
end
end
+
+class ApplicationIntegrationTest < ActionController::IntegrationTest
+ class TestController < ActionController::Base
+ def index
+ render :text => "index"
+ end
+ end
+
+ def self.call(env)
+ routes.call(env)
+ end
+
+ def self.routes
+ @routes ||= ActionDispatch::Routing::RouteSet.new
+ end
+
+ routes.draw do
+ match 'foo', :to => 'application_integration_test/test#index', :as => :foo
+ match 'bar', :to => 'application_integration_test/test#index', :as => :bar
+ end
+
+ def app
+ self.class
+ end
+
+ test "includes route helpers" do
+ assert_equal '/foo', foo_path
+ assert_equal '/bar', bar_path
+ end
+
+ test "route helpers after controller access" do
+ get '/foo'
+ assert_equal '/foo', foo_path
+
+ get '/bar'
+ assert_equal '/bar', bar_path
+ end
+
+ test "missing route helper before controller access" do
+ assert_raise(NameError) { missing_path }
+ end
+
+ test "missing route helper after controller access" do
+ get '/foo'
+ assert_raise(NameError) { missing_path }
+ end
+end
diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb
index 17c645c04c..a9d1c55c05 100644
--- a/actionpack/test/controller/resources_test.rb
+++ b/actionpack/test/controller/resources_test.rb
@@ -126,7 +126,7 @@ class ResourcesTest < ActionController::TestCase
def test_with_custom_conditions
with_restful_routing :messages, :conditions => { :subdomain => 'app' } do
- assert @router.recognize_path("/messages", :method => :get, :subdomain => 'app')
+ assert @routes.recognize_path("/messages", :method => :get, :subdomain => 'app')
end
end
@@ -395,7 +395,7 @@ class ResourcesTest < ActionController::TestCase
assert_restful_routes_for :messages do |options|
assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :get)
assert_raise(ActionController::RoutingError) do
- @router.recognize_path("/messages/new", :method => :post)
+ @routes.recognize_path("/messages/new", :method => :post)
end
end
end
@@ -505,7 +505,7 @@ class ResourcesTest < ActionController::TestCase
def test_restful_routes_dont_generate_duplicates
with_restful_routing :messages do
- routes = @router.routes
+ routes = @routes.routes
routes.each do |route|
routes.each do |r|
next if route === r # skip the comparison instance
@@ -1169,8 +1169,8 @@ class ResourcesTest < ActionController::TestCase
options[:shallow_options] = options[:options]
end
- new_action = @router.resources_path_names[:new] || "new"
- edit_action = @router.resources_path_names[:edit] || "edit"
+ new_action = @routes.resources_path_names[:new] || "new"
+ edit_action = @routes.resources_path_names[:edit] || "edit"
if options[:path_names]
new_action = options[:path_names][:new] if options[:path_names][:new]
@@ -1237,7 +1237,7 @@ class ResourcesTest < ActionController::TestCase
end
@controller = "#{options[:options][:controller].camelize}Controller".constantize.new
- @controller.singleton_class.send(:include, @router.url_helpers)
+ @controller.singleton_class.send(:include, @routes.url_helpers)
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
get :index, options[:options]
@@ -1307,7 +1307,7 @@ class ResourcesTest < ActionController::TestCase
def assert_singleton_named_routes_for(singleton_name, options = {})
(options[:options] ||= {})[:controller] ||= singleton_name.to_s.pluralize
@controller = "#{options[:options][:controller].camelize}Controller".constantize.new
- @controller.singleton_class.send(:include, @router.url_helpers)
+ @controller.singleton_class.send(:include, @routes.url_helpers)
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
get :show, options[:options]
diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb
index f6ba275849..8910454b8b 100644
--- a/actionpack/test/controller/test_test.rb
+++ b/actionpack/test/controller/test_test.rb
@@ -478,8 +478,8 @@ XML
end
def test_with_routing_places_routes_back
- assert @router
- routes_id = @router.object_id
+ assert @routes
+ routes_id = @routes.object_id
begin
with_routing { raise 'fail' }
@@ -487,8 +487,8 @@ XML
rescue RuntimeError
end
- assert @router
- assert_equal routes_id, @router.object_id
+ assert @routes
+ assert_equal routes_id, @routes.object_id
end
def test_remote_addr
diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb
index 7b46a48a1d..a8d7b75372 100644
--- a/actionpack/test/controller/url_rewriter_test.rb
+++ b/actionpack/test/controller/url_rewriter_test.rb
@@ -10,8 +10,8 @@ class UrlRewriterTests < ActionController::TestCase
}
end
- def rewrite(router, options)
- router.url_for(@options.merge(options))
+ def rewrite(routes, options)
+ routes.url_for(@options.merge(options))
end
end
@@ -23,63 +23,63 @@ class UrlRewriterTests < ActionController::TestCase
def test_port
assert_equal('http://test.host:1271/c/a/i',
- @rewriter.rewrite(@router, :controller => 'c', :action => 'a', :id => 'i', :port => 1271)
+ @rewriter.rewrite(@routes, :controller => 'c', :action => 'a', :id => 'i', :port => 1271)
)
end
def test_protocol_with_and_without_separator
assert_equal('https://test.host/c/a/i',
- @rewriter.rewrite(@router, :protocol => 'https', :controller => 'c', :action => 'a', :id => 'i')
+ @rewriter.rewrite(@routes, :protocol => 'https', :controller => 'c', :action => 'a', :id => 'i')
)
assert_equal('https://test.host/c/a/i',
- @rewriter.rewrite(@router, :protocol => 'https://', :controller => 'c', :action => 'a', :id => 'i')
+ @rewriter.rewrite(@routes, :protocol => 'https://', :controller => 'c', :action => 'a', :id => 'i')
)
end
def test_user_name_and_password
assert_equal(
'http://david:secret@test.host/c/a/i',
- @rewriter.rewrite(@router, :user => "david", :password => "secret", :controller => 'c', :action => 'a', :id => 'i')
+ @rewriter.rewrite(@routes, :user => "david", :password => "secret", :controller => 'c', :action => 'a', :id => 'i')
)
end
def test_user_name_and_password_with_escape_codes
assert_equal(
'http://openid.aol.com%2Fnextangler:one+two%3F@test.host/c/a/i',
- @rewriter.rewrite(@router, :user => "openid.aol.com/nextangler", :password => "one two?", :controller => 'c', :action => 'a', :id => 'i')
+ @rewriter.rewrite(@routes, :user => "openid.aol.com/nextangler", :password => "one two?", :controller => 'c', :action => 'a', :id => 'i')
)
end
def test_anchor
assert_equal(
'http://test.host/c/a/i#anchor',
- @rewriter.rewrite(@router, :controller => 'c', :action => 'a', :id => 'i', :anchor => 'anchor')
+ @rewriter.rewrite(@routes, :controller => 'c', :action => 'a', :id => 'i', :anchor => 'anchor')
)
end
def test_anchor_should_call_to_param
assert_equal(
'http://test.host/c/a/i#anchor',
- @rewriter.rewrite(@router, :controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anchor'))
+ @rewriter.rewrite(@routes, :controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anchor'))
)
end
def test_anchor_should_be_cgi_escaped
assert_equal(
'http://test.host/c/a/i#anc%2Fhor',
- @rewriter.rewrite(@router, :controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anc/hor'))
+ @rewriter.rewrite(@routes, :controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anc/hor'))
)
end
def test_trailing_slash
options = {:controller => 'foo', :action => 'bar', :id => '3', :only_path => true}
- assert_equal '/foo/bar/3', @rewriter.rewrite(@router, options)
- assert_equal '/foo/bar/3?query=string', @rewriter.rewrite(@router, options.merge({:query => 'string'}))
+ assert_equal '/foo/bar/3', @rewriter.rewrite(@routes, options)
+ assert_equal '/foo/bar/3?query=string', @rewriter.rewrite(@routes, options.merge({:query => 'string'}))
options.update({:trailing_slash => true})
- assert_equal '/foo/bar/3/', @rewriter.rewrite(@router, options)
+ assert_equal '/foo/bar/3/', @rewriter.rewrite(@routes, options)
options.update({:query => 'string'})
- assert_equal '/foo/bar/3/?query=string', @rewriter.rewrite(@router, options)
+ assert_equal '/foo/bar/3/?query=string', @rewriter.rewrite(@routes, options)
end
end
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index 05545395fb..5942950b15 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -245,7 +245,7 @@ class WebServiceTest < ActionController::IntegrationTest
private
def with_params_parsers(parsers = {})
old_session = @integration_session
- @app = ActionDispatch::ParamsParser.new(app.router, parsers)
+ @app = ActionDispatch::ParamsParser.new(app.routes, parsers)
reset!
yield
ensure
diff --git a/actionpack/test/dispatch/rack_test.rb b/actionpack/test/dispatch/rack_test.rb
index 94eba2a24f..504bebbb86 100644
--- a/actionpack/test/dispatch/rack_test.rb
+++ b/actionpack/test/dispatch/rack_test.rb
@@ -122,7 +122,7 @@ class RackRequestTest < BaseRackTest
test "cgi environment variables" do
assert_equal "Basic", @request.auth_type
assert_equal 0, @request.content_length
- assert_equal nil, @request.content_type
+ assert_equal nil, @request.content_mime_type
assert_equal "CGI/1.1", @request.gateway_interface
assert_equal "*/*", @request.accept
assert_equal "UTF-8", @request.accept_charset
@@ -177,12 +177,12 @@ end
class RackRequestContentTypeTest < BaseRackTest
test "html content type verification" do
@request.env['CONTENT_TYPE'] = Mime::HTML.to_s
- assert @request.content_type.verify_request?
+ assert @request.content_mime_type.verify_request?
end
test "xml content type verification" do
@request.env['CONTENT_TYPE'] = Mime::XML.to_s
- assert !@request.content_type.verify_request?
+ assert !@request.content_mime_type.verify_request?
end
end
diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb
index badef4e92e..9093e1ed65 100644
--- a/actionpack/test/dispatch/request_test.rb
+++ b/actionpack/test/dispatch/request_test.rb
@@ -295,7 +295,7 @@ class RequestTest < ActiveSupport::TestCase
test "content type" do
request = stub_request 'CONTENT_TYPE' => 'text/html'
- assert_equal Mime::HTML, request.content_type
+ assert_equal Mime::HTML, request.content_mime_type
end
test "can override format with parameter" do
@@ -310,17 +310,17 @@ class RequestTest < ActiveSupport::TestCase
test "no content type" do
request = stub_request
- assert_equal nil, request.content_type
+ assert_equal nil, request.content_mime_type
end
test "content type is XML" do
request = stub_request 'CONTENT_TYPE' => 'application/xml'
- assert_equal Mime::XML, request.content_type
+ assert_equal Mime::XML, request.content_mime_type
end
test "content type with charset" do
request = stub_request 'CONTENT_TYPE' => 'application/xml; charset=UTF-8'
- assert_equal Mime::XML, request.content_type
+ assert_equal Mime::XML, request.content_mime_type
end
test "user agent" do
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index c4e71a8689..e58653cb8c 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -114,6 +114,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
resources :comments, :except => :destroy
end
+ resources :sheep
+
match 'sprockets.js' => ::TestRoutingMapper::SprocketsApp
match 'people/:id/update', :to => 'people#update', :as => :update_person
@@ -171,6 +173,12 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
resources :descriptions
root :to => 'projects#index'
end
+
+ resources :products, :constraints => { :id => /\d{4}/ } do
+ resources :images
+ end
+
+ resource :dashboard, :constraints => { :ip => /192\.168\.1\.\d{1,3}/ }
end
end
@@ -525,6 +533,23 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_resource_with_slugs_in_ids
+ with_test_routes do
+ get '/posts/rails-rocks'
+ assert_equal 'posts#show', @response.body
+ assert_equal '/posts/rails-rocks', post_path(:id => 'rails-rocks')
+ end
+ end
+
+ def test_resources_for_uncountable_names
+ with_test_routes do
+ assert_equal '/sheep', sheep_index_path
+ assert_equal '/sheep/1', sheep_path(1)
+ assert_equal '/sheep/new', new_sheep_path
+ assert_equal '/sheep/1/edit', edit_sheep_path(1)
+ end
+ end
+
def test_path_names
with_test_routes do
get '/es/projeto'
@@ -794,6 +819,26 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_resource_constraints
+ with_test_routes do
+ assert_raise(ActionController::RoutingError) { get '/products/1' }
+ get '/products'
+ assert_equal 'products#index', @response.body
+ get '/products/0001'
+ assert_equal 'products#show', @response.body
+
+ assert_raise(ActionController::RoutingError) { get '/products/1/images' }
+ get '/products/0001/images'
+ assert_equal 'images#index', @response.body
+ get '/products/0001/images/1'
+ assert_equal 'images#show', @response.body
+
+ assert_raise(ActionController::RoutingError) { get '/dashboard', {}, {'REMOTE_ADDR' => '10.0.0.100'} }
+ get '/dashboard', {}, {'REMOTE_ADDR' => '192.168.1.100'}
+ assert_equal 'dashboards#show', @response.body
+ end
+ end
+
private
def with_test_routes
yield
diff --git a/actionpack/test/template/active_model_helper_test.rb b/actionpack/test/template/active_model_helper_test.rb
index 7a665b00bc..1a5316a689 100644
--- a/actionpack/test/template/active_model_helper_test.rb
+++ b/actionpack/test/template/active_model_helper_test.rb
@@ -266,6 +266,10 @@ class ActiveModelHelperTest < ActionView::TestCase
assert_dom_equal "<div class=\"differentError\">beforecan't be emptyafter</div>", error_message_on(:post, :author_name, :css_class => 'differentError', :prepend_text => 'before', :append_text => 'after')
end
+ def test_error_message_on_with_tag_option_in_options_hash
+ assert_dom_equal "<span class=\"differentError\">beforecan't be emptyafter</span>", error_message_on(:post, :author_name, :html_tag => "span", :css_class => 'differentError', :prepend_text => 'before', :append_text => 'after')
+ end
+
def test_error_message_on_handles_empty_errors
assert_equal "", error_message_on(@post, :tag)
end
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index c471df861d..fbd504ae7d 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -373,6 +373,22 @@ class AssetTagHelperTest < ActionView::TestCase
assert_equal %(<img alt="Rails" src="/images/rails.png?#{expected_time}" />), image_tag("rails.png")
end
+ def test_string_asset_id
+ @controller.config.asset_path = "/assets.v12345%s"
+
+ expected_path = "/assets.v12345/images/rails.png"
+ assert_equal %(<img alt="Rails" src="#{expected_path}" />), image_tag("rails.png")
+ end
+
+ def test_proc_asset_id
+ @controller.config.asset_path = Proc.new do |asset_path|
+ "/assets.v12345#{asset_path}"
+ end
+
+ expected_path = "/assets.v12345/images/rails.png"
+ assert_equal %(<img alt="Rails" src="#{expected_path}" />), image_tag("rails.png")
+ end
+
def test_timebased_asset_id_with_relative_url_root
@controller.config.relative_url_root = "/collaboration/hieraki"
expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s
diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb
index 195a6ea3ae..c1a38a25de 100644
--- a/actionpack/test/template/test_case_test.rb
+++ b/actionpack/test/template/test_case_test.rb
@@ -114,7 +114,7 @@ module ActionView
end
test "is able to use routes" do
- controller.request.assign_parameters(@router, 'foo', 'index')
+ controller.request.assign_parameters(@routes, 'foo', 'index')
assert_equal '/foo', url_for
assert_equal '/bar', url_for(:controller => 'bar')
end
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index cb67ef7270..2d5acdfced 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -1,4 +1,7 @@
+require 'active_model/attribute_methods'
+require 'active_support/concern'
require 'active_support/hash_with_indifferent_access'
+require 'active_support/core_ext/object/duplicable'
module ActiveModel
# <tt>ActiveModel::Dirty</tt> provides a way to track changes in your
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index a9a54a90e0..8d28040c32 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/string/inflections'
+require 'active_support/core_ext/object/blank'
require 'active_support/ordered_hash'
module ActiveModel
diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb
index 0c1334fe1b..c1838bb93e 100644
--- a/activemodel/lib/active_model/validations/inclusion.rb
+++ b/activemodel/lib/active_model/validations/inclusion.rb
@@ -4,7 +4,7 @@ module ActiveModel
def check_validity!
raise ArgumentError, "An object with the method include? is required must be supplied as the " <<
":in option of the configuration hash" unless options[:in].respond_to?(:include?)
- end
+ end
def validate_each(record, attribute, value)
return if options[:in].include?(value)
diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb
index b7c52be3f0..906d239bcc 100644
--- a/activemodel/lib/active_model/validator.rb
+++ b/activemodel/lib/active_model/validator.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/array/wrap'
require "active_support/core_ext/module/anonymous"
+require 'active_support/core_ext/object/blank'
module ActiveModel #:nodoc:
# A simple base class that can be used along with
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 214ec8c1d8..e379f4f967 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,9 +1,11 @@
-*Edge*
+*Rails 3.0.0 [Beta 2] (pending)*
+
+* To prefix the table names of all models in a module, define self.table_name_prefix on the module. #4032 [Andrew White]
* Silenced "SHOW FIELDS" and "SET SQL_AUTO_IS_NULL=0" statements from the MySQL driver to improve log signal to noise ration in development [DHH]
-*Rails 3.0 [Beta] (February 4th, 2010)*
+*Rails 3.0.0 [Beta 1] (February 4th, 2010)*
* PostgreSQLAdapter: set time_zone to UTC when Base.default_timezone == :utc so that Postgres doesn't incorrectly offset-adjust values inserted into TIMESTAMP WITH TIME ZONE columns. #3777 [Jack Christensen]
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index 5942640c85..8a1aa50e24 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -111,10 +111,10 @@ module ActiveRecord
autoload :TestCase
autoload :TestFixtures, 'active_record/fixtures'
+end
- base_hook do
- Arel::Table.engine = Arel::Sql::Engine.new(self)
- end
+ActiveSupport.on_load(:active_record) do
+ Arel::Table.engine = Arel::Sql::Engine.new(self)
end
I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml' \ No newline at end of file
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
index 6725d4e88b..95bbaf00cf 100644
--- a/activerecord/lib/active_record/association_preload.rb
+++ b/activerecord/lib/active_record/association_preload.rb
@@ -159,6 +159,11 @@ module ActiveRecord
association_proxy.__send__(:set_inverse_instance, associated_record, mapped_record)
end
end
+
+ id_to_record_map.each do |id, records|
+ next if seen_keys.include?(id.to_s)
+ records.each {|record| record.send("set_#{reflection_name}_target", nil) }
+ end
end
# Given a collection of ActiveRecord objects, constructs a Hash which maps
@@ -324,7 +329,7 @@ module ActiveRecord
klass = klass_name.constantize
table_name = klass.quoted_table_name
- primary_key = klass.primary_key
+ primary_key = reflection.options[:primary_key] || klass.primary_key
column_type = klass.columns.detect{|c| c.name == primary_key}.type
ids = id_map.keys.map do |id|
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index d623ddb915..7406daf837 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/enumerable'
+require 'active_support/core_ext/object/blank'
module ActiveRecord
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
@@ -85,6 +86,15 @@ module ActiveRecord
end
end
+ # This error is raised when trying to destroy a parent instance in a N:1, 1:1 assosications
+ # (has_many, has_one) when there is at least 1 child assosociated instance.
+ # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
+ class DeleteRestrictionError < ActiveRecordError #:nodoc:
+ def initialize(reflection)
+ super("Cannot delete record because of dependent #{reflection.name}")
+ end
+ end
+
# See ActiveRecord::Associations::ClassMethods for documentation.
module Associations # :nodoc:
extend ActiveSupport::Concern
@@ -830,6 +840,8 @@ module ActiveRecord
# objects are deleted *without* calling their +destroy+ method. If set to <tt>:nullify</tt> all associated
# objects' foreign keys are set to +NULL+ *without* calling their +save+ callbacks. *Warning:* This option is ignored when also using
# the <tt>:through</tt> option.
+ # the <tt>:through</tt> option. If set to <tt>:restrict</tt>
+ # this object cannot be deleted if it has any associated object.
# [:finder_sql]
# Specify a complete SQL statement to fetch the association. This is a good way to go for complex
# associations that depend on multiple tables. Note: When this option is used, +find_in_collection+ is _not_ added.
@@ -1468,9 +1480,15 @@ module ActiveRecord
# Creates before_destroy callback methods that nullify, delete or destroy
# has_many associated objects, according to the defined :dependent rule.
+ # If the association is marked as :dependent => :restrict, create a callback
+ # that prevents deleting entirely.
#
# See HasManyAssociation#delete_records. Dependent associations
# delete children, otherwise foreign key is set to NULL.
+ # See HasManyAssociation#delete_records. Dependent associations
+ # delete children if the option is set to :destroy or :delete_all, set the
+ # foreign key to NULL if the option is set to :nullify, and do not touch the
+ # child records if the option is set to :restrict.
#
# The +extra_conditions+ parameter, which is not used within the main
# Active Record codebase, is meant to allow plugins to define extra
@@ -1530,14 +1548,24 @@ module ActiveRecord
%@#{dependent_conditions}@)
end
CALLBACK
+ when :restrict
+ method_name = "has_many_dependent_restrict_for_#{reflection.name}".to_sym
+ define_method(method_name) do
+ unless send(reflection.name).empty?
+ raise DeleteRestrictionError.new(reflection)
+ end
+ end
+ before_destroy method_name
else
- raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, or :nullify (#{reflection.options[:dependent].inspect})"
+ raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, :nullify or :restrict (#{reflection.options[:dependent].inspect})"
end
end
end
# Creates before_destroy callback methods that nullify, delete or destroy
# has_one associated objects, according to the defined :dependent rule.
+ # If the association is marked as :dependent => :restrict, create a callback
+ # that prevents deleting entirely.
def configure_dependency_for_has_one(reflection)
if reflection.options.include?(:dependent)
name = reflection.options[:dependent]
@@ -1558,8 +1586,16 @@ module ActiveRecord
association.update_attribute(#{reflection.primary_key_name.inspect}, nil) if association
end
eoruby
+ when :restrict
+ method_name = "has_one_dependent_restrict_for_#{reflection.name}".to_sym
+ define_method(method_name) do
+ unless send(reflection.name).nil?
+ raise DeleteRestrictionError.new(reflection)
+ end
+ end
+ before_destroy method_name
else
- raise ArgumentError, "The :dependent option expects either :destroy, :delete or :nullify (#{reflection.options[:dependent].inspect})"
+ raise ArgumentError, "The :dependent option expects either :destroy, :delete, :nullify or :restrict (#{reflection.options[:dependent].inspect})"
end
before_destroy method_name
@@ -1995,7 +2031,7 @@ module ActiveRecord
[aliased_table[foreign_key].eq(parent_table[reflection.options[:primary_key] || parent.primary_key])]
end
when :belongs_to
- [aliased_table[reflection.klass.primary_key].eq(parent_table[options[:foreign_key] || reflection.primary_key_name])]
+ [aliased_table[options[:primary_key] || reflection.klass.primary_key].eq(parent_table[options[:foreign_key] || reflection.primary_key_name])]
end
unless klass.descends_from_active_record?
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index bd2acd4340..5338bb099d 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -1,4 +1,5 @@
require "active_record/associations/through_association_scope"
+require 'active_support/core_ext/object/blank'
module ActiveRecord
module Associations
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index a8698a2f5a..435aea9b09 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
module AttributeMethods
module Dirty
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 095814b635..411330dda2 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -3,6 +3,12 @@ module ActiveRecord
module PrimaryKey
extend ActiveSupport::Concern
+ # Returns this record's primary key value wrapped in an Array
+ # or nil if the record is a new_record?
+ def to_key
+ new_record? ? nil : [ send(self.class.primary_key) ]
+ end
+
module ClassMethods
# Defines the primary key field -- can be overridden in subclasses. Overwriting will negate any effect of the
# primary_key_prefix_type setting, though.
@@ -39,22 +45,6 @@ module ActiveRecord
end
alias :primary_key= :set_primary_key
end
-
- module InstanceMethods
-
- # Returns this record's primary key value wrapped in an Array
- # or nil if the record is a new_record?
- # This is done to comply with the AMo interface that expects
- # every AMo compliant object to respond_to?(:to_key) and return
- # an Enumerable object from that call, or nil if new_record?
- # This method also takes custom primary keys specified via
- # the +set_primary_key+ into account.
- def to_key
- new_record? ? nil : [ self.primary_key ]
- end
-
- end
-
end
end
end
diff --git a/activerecord/lib/active_record/attribute_methods/query.rb b/activerecord/lib/active_record/attribute_methods/query.rb
index a949d80120..948809c65a 100644
--- a/activerecord/lib/active_record/attribute_methods/query.rb
+++ b/activerecord/lib/active_record/attribute_methods/query.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
module AttributeMethods
module Query
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 1c93346a52..37b379af9e 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -13,6 +13,8 @@ require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/string/behavior'
require 'active_support/core_ext/object/singleton_class'
require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/object/duplicable'
+require 'active_support/core_ext/object/blank'
require 'arel'
require 'active_record/errors'
@@ -336,6 +338,9 @@ module ActiveRecord #:nodoc:
# Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all
# table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace
# for tables in a shared database. By default, the prefix is the empty string.
+ #
+ # If you are organising your models within modules you can add a prefix to the models within a namespace by defining
+ # a singleton method in the parent module called table_name_prefix which returns your chosen prefix.
cattr_accessor :table_name_prefix, :instance_writer => false
@@table_name_prefix = ""
@@ -763,7 +768,7 @@ module ActiveRecord #:nodoc:
contained = contained.singularize if parent.pluralize_table_names
contained << '_'
end
- name = "#{table_name_prefix}#{contained}#{undecorated_table_name(base.name)}#{table_name_suffix}"
+ name = "#{full_table_name_prefix}#{contained}#{undecorated_table_name(base.name)}#{table_name_suffix}"
end
@quoted_table_name = nil
@@ -771,6 +776,10 @@ module ActiveRecord #:nodoc:
name
end
+ def full_table_name_prefix #:nodoc:
+ (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
+ end
+
# Defines the column name for use with single table inheritance
# -- can be set in subclasses like so: self.inheritance_column = "type_id"
def inheritance_column
@@ -1288,7 +1297,7 @@ module ActiveRecord #:nodoc:
# <tt>options</tt> argument is the same as in find.
#
# class Person < ActiveRecord::Base
- # default_scope :order => 'last_name, first_name'
+ # default_scope order('last_name, first_name')
# end
def default_scope(options = {})
self.default_scoping << construct_finder_arel(options)
@@ -2214,6 +2223,7 @@ module ActiveRecord #:nodoc:
extend QueryCache::ClassMethods
extend ActiveSupport::Benchmarkable
+ include ActiveModel::Conversion
include Validations
include Locking::Optimistic, Locking::Pessimistic
include AttributeMethods
@@ -2223,12 +2233,10 @@ module ActiveRecord #:nodoc:
include AttributeMethods::Dirty
include Callbacks, ActiveModel::Observing, Timestamp
include Associations, AssociationPreload, NamedScope
- include ActiveModel::Conversion
# AutosaveAssociation needs to be included before Transactions, because we want
# #save_with_autosave_associations to be wrapped inside a transaction.
include AutosaveAssociation, NestedAttributes
-
include Aggregations, Transactions, Reflection, Serialization
NilClass.add_whiner(self) if NilClass.respond_to?(:add_whiner)
@@ -2237,4 +2245,4 @@ end
# TODO: Remove this and make it work with LAZY flag
require 'active_record/connection_adapters/abstract_adapter'
-ActiveRecord.run_base_hooks(ActiveRecord::Base)
+ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
index 020acbbe5a..1e095110f2 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/duplicable'
+
module ActiveRecord
module ConnectionAdapters # :nodoc:
module QueryCache
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index 64faaef4a0..046825d43f 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/object/blank'
require 'date'
require 'set'
require 'bigdecimal'
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 521bd810d0..55d9d20bb5 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -1,5 +1,6 @@
require 'active_record/connection_adapters/abstract_adapter'
require 'active_support/core_ext/kernel/requires'
+require 'active_support/core_ext/object/blank'
require 'set'
module MysqlCompat #:nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 31d5266da8..a6042e1382 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -1,5 +1,6 @@
require 'active_record/connection_adapters/abstract_adapter'
require 'active_support/core_ext/kernel/requires'
+require 'active_support/core_ext/object/blank'
begin
require_library_or_gem 'pg'
@@ -299,7 +300,7 @@ module ActiveRecord
# QUOTING ==================================================
# Escapes binary strings for bytea input to the database.
- def escape_bytea(value)
+ def escape_bytea(original_value)
if @connection.respond_to?(:escape_bytea)
self.class.instance_eval do
define_method(:escape_bytea) do |value|
@@ -323,13 +324,13 @@ module ActiveRecord
end
end
end
- escape_bytea(value)
+ escape_bytea(original_value)
end
# Unescapes bytea output from a database to the binary string it represents.
# NOTE: This is NOT an inverse of escape_bytea! This is only to be used
# on escaped binary output from database drive.
- def unescape_bytea(value)
+ def unescape_bytea(original_value)
# In each case, check if the value actually is escaped PostgreSQL bytea output
# or an unescaped Active Record attribute that was just written.
if PGconn.respond_to?(:unescape_bytea)
@@ -369,7 +370,7 @@ module ActiveRecord
end
end
end
- unescape_bytea(value)
+ unescape_bytea(original_value)
end
# Quotes PostgreSQL-specific data types for SQL input.
@@ -394,7 +395,7 @@ module ActiveRecord
end
# Quotes strings for use in SQL input in the postgres driver for better performance.
- def quote_string(s) #:nodoc:
+ def quote_string(original_value) #:nodoc:
if @connection.respond_to?(:escape)
self.class.instance_eval do
define_method(:quote_string) do |s|
@@ -414,7 +415,7 @@ module ActiveRecord
remove_method(:quote_string)
end
end
- quote_string(s)
+ quote_string(original_value)
end
# Checks the following cases:
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 79f70f07cd..22f0e60083 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -4,6 +4,7 @@ require 'csv'
require 'zlib'
require 'active_support/dependencies'
require 'active_support/core_ext/logger'
+require 'active_support/core_ext/object/blank'
if RUBY_VERSION < '1.9'
module YAML #:nodoc:
diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb
index 394e1587e1..9abf979cd0 100644
--- a/activerecord/lib/active_record/named_scope.rb
+++ b/activerecord/lib/active_record/named_scope.rb
@@ -1,6 +1,7 @@
require 'active_support/core_ext/array'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/object/singleton_class'
+require 'active_support/core_ext/object/blank'
module ActiveRecord
module NamedScope
@@ -101,7 +102,8 @@ module ActiveRecord
name = name.to_sym
if !scopes[name] && respond_to?(name, true)
- raise ArgumentError, "Cannot define scope :#{name} because #{self.name}.#{name} method already exists."
+ logger.warn "Creating scope :#{name}. " \
+ "Overwriting existing method #{self.name}.#{name}."
end
scopes[name] = lambda do |parent_scope, *args|
@@ -165,7 +167,14 @@ module ActiveRecord
end
def ==(other)
- other.respond_to?(:to_ary) ? to_a == other.to_a : false
+ case other
+ when Scope
+ to_sql == other.to_sql
+ when Relation
+ other == self
+ when Array
+ to_a == other.to_a
+ end
end
private
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index 76ec7eb681..ee2d420194 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/object/try'
+require 'active_support/core_ext/object/blank'
module ActiveRecord
module NestedAttributes #:nodoc:
diff --git a/activerecord/lib/active_record/query_cache.rb b/activerecord/lib/active_record/query_cache.rb
index eb92bc2545..093c6c1e55 100644
--- a/activerecord/lib/active_record/query_cache.rb
+++ b/activerecord/lib/active_record/query_cache.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
class QueryCache
module ClassMethods
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index de47461c73..04c4a9c153 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -23,18 +23,18 @@ module ActiveRecord
log_subscriber :active_record, ActiveRecord::Railties::LogSubscriber.new
initializer "active_record.initialize_timezone" do
- ActiveRecord.base_hook do
+ ActiveSupport.on_load(:active_record) do
self.time_zone_aware_attributes = true
self.default_timezone = :utc
end
end
initializer "active_record.logger" do
- ActiveRecord.base_hook { self.logger ||= ::Rails.logger }
+ ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
end
initializer "active_record.set_configs" do |app|
- ActiveRecord.base_hook do
+ ActiveSupport.on_load(:active_record) do
app.config.active_record.each do |k,v|
send "#{k}=", v
end
@@ -44,7 +44,7 @@ module ActiveRecord
# This sets the database configuration from Configuration#database_configuration
# and then establishes the connection.
initializer "active_record.initialize_database" do |app|
- ActiveRecord.base_hook do
+ ActiveSupport.on_load(:active_record) do
self.configurations = app.config.database_configuration
establish_connection
end
@@ -53,7 +53,7 @@ module ActiveRecord
# Expose database runtime to controller for logging.
initializer "active_record.log_runtime" do |app|
require "active_record/railties/controller_runtime"
- ActionController.base_hook do
+ ActiveSupport.on_load(:action_controller) do
include ActiveRecord::Railties::ControllerRuntime
end
end
@@ -71,9 +71,9 @@ module ActiveRecord
end
initializer "active_record.load_observers" do
- ActiveRecord.base_hook { instantiate_observers }
+ ActiveSupport.on_load(:active_record) { instantiate_observers }
- ActiveRecord.base_hook do
+ ActiveSupport.on_load(:active_record) do
ActionDispatch::Callbacks.to_prepare(:activerecord_instantiate_observers) do
ActiveRecord::Base.instantiate_observers
end
@@ -81,7 +81,7 @@ module ActiveRecord
end
initializer "active_record.set_dispatch_hooks", :before => :set_clear_dependencies_hook do |app|
- ActiveRecord.base_hook do
+ ActiveSupport.on_load(:active_record) do
unless app.config.cache_classes
ActionDispatch::Callbacks.after do
ActiveRecord::Base.reset_subclasses
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index a20c152eeb..8577ec58f7 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
class Relation
JoinOperation = Struct.new(:relation, :join_class, :on)
diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb
index 4a260d4caa..1c61e7d450 100644
--- a/activerecord/lib/active_record/relation/batches.rb
+++ b/activerecord/lib/active_record/relation/batches.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
module Batches # :nodoc:
# Yields each record that was found by the find +options+. The find is
@@ -48,6 +50,10 @@ module ActiveRecord
def find_in_batches(options = {})
relation = self
+ if orders.present? || taken.present?
+ ActiveRecord::Base.logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size")
+ end
+
if (finder_options = options.except(:start, :batch_size)).present?
raise "You can't specify an order, it's forced to be #{batch_order}" if options[:order].present?
raise "You can't specify a limit, it's forced to be the batch_size" if options[:limit].present?
@@ -75,4 +81,4 @@ module ActiveRecord
"#{@klass.table_name}.#{@klass.primary_key} ASC"
end
end
-end \ No newline at end of file
+end
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index e77424a64b..a5ea6e7e3a 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
module Calculations
# Count operates using three different approaches.
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index c1cce679b6..37aaac0894 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
module FinderMethods
# Find operates with four different retrieval approaches:
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 7e83eccbb5..711df16bf1 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -27,12 +27,7 @@ module ActiveRecord
values = value.to_a
attribute.in(values)
when Range
- # TODO : Arel should handle ranges with excluded end.
- if value.exclude_end?
- [attribute.gteq(value.begin), attribute.lt(value.end)]
- else
- attribute.in(value)
- end
+ attribute.in(value)
else
attribute.eq(value)
end
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 0250e739b8..e224781016 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
module QueryMethods
extend ActiveSupport::Concern
diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb
index 2841ff1239..a17de1bdbb 100644
--- a/activerecord/lib/active_record/relation/spawn_methods.rb
+++ b/activerecord/lib/active_record/relation/spawn_methods.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
module SpawnMethods
def merge(r)
diff --git a/activerecord/lib/active_record/schema.rb b/activerecord/lib/active_record/schema.rb
index a996a0ebac..a833356d15 100644
--- a/activerecord/lib/active_record/schema.rb
+++ b/activerecord/lib/active_record/schema.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveRecord
# Allows programmers to programmatically define a schema in a portable
# DSL. This means you can define tables, indexes, etc. without using SQL
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index e28808df98..4806fa0ecc 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -67,13 +67,11 @@ module ActiveRecord
if value.nil? || (options[:case_sensitive] || !column.text?)
sql = "#{sql_attribute} #{operator}"
- params = [value]
else
- sql = "LOWER(#{sql_attribute}) #{operator}"
- params = [value.mb_chars.downcase]
+ sql = "LOWER(#{sql_attribute}) = LOWER(?)"
end
- [sql, params]
+ [sql, [value]]
end
end
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 41a23d7f61..62121b93cb 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -32,6 +32,17 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal companies(:first_firm).name, client.firm_with_primary_key.name
end
+ def test_belongs_to_with_primary_key_joins_on_correct_column
+ sql = Client.joins(:firm_with_primary_key).to_sql
+ if current_adapter?(:MysqlAdapter)
+ assert_no_match /`firm_with_primary_keys_companies`\.`id`/, sql
+ assert_match /`firm_with_primary_keys_companies`\.`name`/, sql
+ else
+ assert_no_match /"firm_with_primary_keys_companies"\."id"/, sql
+ assert_match /"firm_with_primary_keys_companies"\."name"/, sql
+ end
+ end
+
def test_proxy_assignment
account = Account.find(1)
assert_nothing_raised { account.firm = account.firm }
@@ -61,6 +72,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal apple.name, citibank.firm_name
end
+ def test_eager_loading_with_primary_key
+ apple = Firm.create("name" => "Apple")
+ citibank = Client.create("name" => "Citibank", :firm_name => "Apple")
+ citibank_result = Client.find(:first, :conditions => {:name => "Citibank"}, :include => :firm_with_primary_key)
+ assert_not_nil citibank_result.instance_variable_get("@firm_with_primary_key")
+ end
+
def test_no_unexpected_aliasing
first_firm = companies(:first_firm)
another_firm = companies(:another_firm)
@@ -439,9 +457,15 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal [author_address.id], AuthorAddress.destroyed_author_address_ids
end
- def test_invalid_belongs_to_dependent_option_raises_exception
+ def test_invalid_belongs_to_dependent_option_nullify_raises_exception
assert_raise ArgumentError do
Author.belongs_to :special_author_address, :dependent => :nullify
end
end
+
+ def test_invalid_belongs_to_dependent_option_restrict_raises_exception
+ assert_raise ArgumentError do
+ Author.belongs_to :special_author_address, :dependent => :restrict
+ end
+ end
end
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 42a891bc3b..79e5ecf4ce 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -833,4 +833,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
end
+ def test_preloading_empty_polymorphic_parent
+ t = Tagging.create!(:taggable_type => 'Post', :taggable_id => Post.maximum(:id) + 1, :tag => tags(:general))
+
+ assert_queries(2) { @tagging = Tagging.preload(:taggable).find(t.id) }
+ assert_no_queries { assert ! @tagging.taggable }
+ end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 54624e79ce..c1e539d573 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -836,6 +836,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal num_accounts, Account.count
end
+ def test_restrict
+ firm = RestrictedFirm.new(:name => 'restrict')
+ firm.save!
+ child_firm = firm.companies.create(:name => 'child')
+ assert !firm.companies.empty?
+ assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
+ end
+
def test_included_in_collection
assert companies(:first_firm).clients.include?(Client.find(2))
end
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index 7372f2da1b..8f5540950e 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -177,7 +177,15 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_nothing_raised { firm.destroy }
end
- def test_succesful_build_association
+ def test_dependence_with_restrict
+ firm = RestrictedFirm.new(:name => 'restrict')
+ firm.save!
+ account = firm.create_account(:credit_limit => 10)
+ assert !firm.account.nil?
+ assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
+ end
+
+ def test_successful_build_association
firm = Firm.new("name" => "GlobalMegaCorp")
firm.save
diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb
index e417d8a803..83deabb5b7 100644
--- a/activerecord/test/cases/batches_test.rb
+++ b/activerecord/test/cases/batches_test.rb
@@ -8,7 +8,7 @@ class EachTest < ActiveRecord::TestCase
@posts = Post.order("id asc")
@total = Post.count
end
-
+
def test_each_should_excecute_one_query_per_batch
assert_queries(Post.count + 1) do
Post.find_each(:batch_size => 1) do |post|
@@ -28,7 +28,17 @@ class EachTest < ActiveRecord::TestCase
Post.find_each(:limit => 1) { |post| post }
end
end
-
+
+ def test_warn_if_limit_scope_is_set
+ ActiveRecord::Base.logger.expects(:warn)
+ Post.limit(1).find_each { |post| post }
+ end
+
+ def test_warn_if_order_scope_is_set
+ ActiveRecord::Base.logger.expects(:warn)
+ Post.order("title").find_each { |post| post }
+ end
+
def test_find_in_batches_should_return_batches
assert_queries(Post.count + 1) do
Post.find_in_batches(:batch_size => 1) do |batch|
@@ -58,4 +68,4 @@ class EachTest < ActiveRecord::TestCase
Post.find_in_batches(:batch_size => post_count + 1) {|batch| assert_kind_of Array, batch }
end
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/cases/modules_test.rb b/activerecord/test/cases/modules_test.rb
index d781a229f4..7209966bf8 100644
--- a/activerecord/test/cases/modules_test.rb
+++ b/activerecord/test/cases/modules_test.rb
@@ -82,4 +82,32 @@ class ModulesTest < ActiveRecord::TestCase
end
end
end
+
+ def test_module_table_name_prefix
+ assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Company.table_name, 'inferred table_name for ActiveRecord model in module with table_name_prefix'
+ assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Nested::Company.table_name, 'table_name for ActiveRecord model in nested module with a parent table_name_prefix'
+ assert_equal 'companies', MyApplication::Business::Prefixed::Firm.table_name, 'explicit table_name for ActiveRecord model in module with table_name_prefix should not be prefixed'
+ end
+
+ def test_module_table_name_prefix_with_global_prefix
+ classes = [ MyApplication::Business::Company,
+ MyApplication::Business::Firm,
+ MyApplication::Business::Client,
+ MyApplication::Business::Client::Contact,
+ MyApplication::Business::Developer,
+ MyApplication::Business::Project,
+ MyApplication::Business::Prefixed::Company,
+ MyApplication::Business::Prefixed::Nested::Company,
+ MyApplication::Billing::Account ]
+
+ ActiveRecord::Base.table_name_prefix = 'global_'
+ classes.each(&:reset_table_name)
+ assert_equal 'global_companies', MyApplication::Business::Company.table_name, 'inferred table_name for ActiveRecord model in module without table_name_prefix'
+ assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Company.table_name, 'inferred table_name for ActiveRecord model in module with table_name_prefix'
+ assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Nested::Company.table_name, 'table_name for ActiveRecord model in nested module with a parent table_name_prefix'
+ assert_equal 'companies', MyApplication::Business::Prefixed::Firm.table_name, 'explicit table_name for ActiveRecord model in module with table_name_prefix should not be prefixed'
+ ensure
+ ActiveRecord::Base.table_name_prefix = ''
+ classes.each(&:reset_table_name)
+ end
end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index 6c2b4fa3a7..2396ca10b0 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -371,8 +371,21 @@ class NamedScopeTest < ActiveRecord::TestCase
end
def test_named_scopes_with_reserved_names
- [:where, :with_scope].each do |protected_method|
- assert_raises(ArgumentError) { Topic.scope protected_method }
+ class << Topic
+ def public_method; end
+ public :public_method
+
+ def protected_method; end
+ protected :protected_method
+
+ def private_method; end
+ private :private_method
+ end
+
+ [:public_method, :protected_method, :private_method].each do |reserved_method|
+ assert Topic.respond_to?(reserved_method, true)
+ ActiveRecord::Base.logger.expects(:warn)
+ Topic.scope(reserved_method)
end
end
@@ -394,6 +407,12 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_equal topics(:second), approved[0]
assert approved.loaded?
end
+
+ def test_nested_named_scopes_queries_size
+ assert_queries(1) do
+ Topic.approved.by_lifo.replied.written_before(Time.now).all
+ end
+ end
end
class DynamicScopeMatchTest < ActiveRecord::TestCase
diff --git a/activerecord/test/cases/pk_test.rb b/activerecord/test/cases/pk_test.rb
index 5bba1d5625..33ad5992de 100644
--- a/activerecord/test/cases/pk_test.rb
+++ b/activerecord/test/cases/pk_test.rb
@@ -23,6 +23,12 @@ class PrimaryKeysTest < ActiveRecord::TestCase
assert_equal keyboard.to_key, [keyboard.id]
end
+ def test_to_key_with_primary_key_after_destroy
+ topic = Topic.find(1)
+ topic.destroy
+ assert_equal topic.to_key, [1]
+ end
+
def test_integer_key
topic = Topic.find(1)
assert_equal(topics(:first).author_name, topic.author_name)
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index f31d5f87e5..be6dd71e3b 100644
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -95,6 +95,11 @@ class DependentFirm < Company
has_many :companies, :foreign_key => 'client_of', :dependent => :nullify
end
+class RestrictedFirm < Company
+ has_one :account, :foreign_key => "firm_id", :dependent => :restrict, :order => "id"
+ has_many :companies, :foreign_key => 'client_of', :order => "id", :dependent => :restrict
+end
+
class Client < Company
belongs_to :firm, :foreign_key => "client_of"
belongs_to :firm_with_basic_id, :class_name => "Firm", :foreign_key => "firm_id"
diff --git a/activerecord/test/models/company_in_module.rb b/activerecord/test/models/company_in_module.rb
index cdda7a44d4..83d71b6909 100644
--- a/activerecord/test/models/company_in_module.rb
+++ b/activerecord/test/models/company_in_module.rb
@@ -32,6 +32,23 @@ module MyApplication
has_and_belongs_to_many :developers
end
+ module Prefixed
+ def self.table_name_prefix
+ 'prefixed_'
+ end
+
+ class Company < ActiveRecord::Base
+ end
+
+ class Firm < Company
+ self.table_name = 'companies'
+ end
+
+ module Nested
+ class Company < ActiveRecord::Base
+ end
+ end
+ end
end
module Billing
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index 67296a171a..5cfe4f7c7d 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -9,6 +9,7 @@ require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/misc'
require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/object/duplicable'
require 'set'
require 'uri'
diff --git a/activeresource/lib/active_resource/custom_methods.rb b/activeresource/lib/active_resource/custom_methods.rb
index ff14b49b07..dd3e35dfc7 100644
--- a/activeresource/lib/active_resource/custom_methods.rb
+++ b/activeresource/lib/active_resource/custom_methods.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveResource
# A module to support custom REST methods and sub-resources, allowing you to break out
# of the "default" REST methods with your own custom resource requests. For example,
diff --git a/activeresource/lib/active_resource/validations.rb b/activeresource/lib/active_resource/validations.rb
index 4774c6dd22..a19e0d0ac9 100644
--- a/activeresource/lib/active_resource/validations.rb
+++ b/activeresource/lib/active_resource/validations.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/object/blank'
module ActiveResource
class ResourceInvalid < ClientError #:nodoc:
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 56c81cf63b..3822abcab6 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.0 (pending)*
+* New assertions assert_blank and assert_present. #4299 [Juanjo Bazan]
+
* Use Object#singleton_class instead of #metaclass. Prefer Ruby's choice. [Jeremy Kemper]
* JSON backend for YAJL. Preferred if available. #2666 [Brian Lopez]
diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index d584c9e254..d84a62ca2d 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -91,7 +91,7 @@ module ActiveSupport
def delete(key, options = nil) # :nodoc:
super do
- response = @data.delete(key, expires_in(options))
+ response = @data.delete(key)
response == Response::DELETED
end
rescue MemCache::MemCacheError => e
diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb
index e4d429fc2b..045a6944fa 100644
--- a/activesupport/lib/active_support/core_ext/hash/keys.rb
+++ b/activesupport/lib/active_support/core_ext/hash/keys.rb
@@ -22,7 +22,7 @@ class Hash
# to +to_sym+.
def symbolize_keys!
keys.each do |key|
- self[(key.to_sym rescue key)] = delete(key) if key.respond_to?(:to_sym) && !key.is_a?(Fixnum)
+ self[(key.to_sym rescue key) || key] = delete(key)
end
self
end
diff --git a/activesupport/lib/active_support/core_ext/time/marshal.rb b/activesupport/lib/active_support/core_ext/time/marshal.rb
new file mode 100644
index 0000000000..1a4d918ce7
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/time/marshal.rb
@@ -0,0 +1,56 @@
+# Pre-1.9 versions of Ruby have a bug with marshaling Time instances, where utc instances are
+# unmarshalled in the local zone, instead of utc. We're layering behavior on the _dump and _load
+# methods so that utc instances can be flagged on dump, and coerced back to utc on load.
+if !Marshal.load(Marshal.dump(Time.now.utc)).utc?
+ class Time
+ class << self
+ alias_method :_load_without_utc_flag, :_load
+ def _load(marshaled_time)
+ time = _load_without_utc_flag(marshaled_time)
+ time.instance_eval do
+ if defined?(@marshal_with_utc_coercion)
+ val = remove_instance_variable("@marshal_with_utc_coercion")
+ end
+ val ? utc : self
+ end
+ end
+ end
+
+ alias_method :_dump_without_utc_flag, :_dump
+ def _dump(*args)
+ obj = dup
+ obj.instance_variable_set('@marshal_with_utc_coercion', utc?)
+ obj._dump_without_utc_flag(*args)
+ end
+ end
+end
+
+# Ruby 1.9.2 adds utc_offset and zone to Time, but marshaling only
+# preserves utc_offset. Preserve zone also, even though it may not
+# work in some edge cases.
+if Time.local(2010).zone != Marshal.load(Marshal.dump(Time.local(2010))).zone
+ class Time
+ class << self
+ alias_method :_load_without_zone, :_load
+ def _load(marshaled_time)
+ time = _load_without_zone(marshaled_time)
+ time.instance_eval do
+ if zone = defined?(@_zone) && remove_instance_variable('@_zone')
+ ary = to_a
+ ary[-1] = zone
+ utc? ? Time.utc(*ary) : Time.local(*ary)
+ else
+ self
+ end
+ end
+ end
+ end
+
+ alias_method :_dump_without_zone, :_dump
+ def _dump(*args)
+ obj = dup
+ obj.instance_variable_set('@_zone', zone)
+ obj._dump_without_zone(*args)
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb b/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb
deleted file mode 100644
index 8d46d80251..0000000000
--- a/activesupport/lib/active_support/core_ext/time/marshal_with_utc_flag.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# Pre-1.9 versions of Ruby have a bug with marshaling Time instances, where utc instances are
-# unmarshalled in the local zone, instead of utc. We're layering behavior on the _dump and _load
-# methods so that utc instances can be flagged on dump, and coerced back to utc on load.
-if RUBY_VERSION < '1.9'
- class Time
- class << self
- alias_method :_original_load, :_load
- def _load(marshaled_time)
- time = _original_load(marshaled_time)
- time.instance_eval do
- if defined?(@marshal_with_utc_coercion)
- val = remove_instance_variable("@marshal_with_utc_coercion")
- end
- val ? utc : self
- end
- end
- end
-
- alias_method :_original_dump, :_dump
- def _dump(*args)
- obj = dup
- obj.instance_variable_set('@marshal_with_utc_coercion', utc?)
- obj._original_dump(*args)
- end
- end
-end
diff --git a/activesupport/lib/active_support/dependencies/autoload.rb b/activesupport/lib/active_support/dependencies/autoload.rb
index f669f4a77e..4c771da096 100644
--- a/activesupport/lib/active_support/dependencies/autoload.rb
+++ b/activesupport/lib/active_support/dependencies/autoload.rb
@@ -3,10 +3,6 @@ require "active_support/lazy_load_hooks"
module ActiveSupport
module Autoload
- def self.extended(base)
- base.extend(LazyLoadHooks)
- end
-
@@autoloads = {}
@@under_path = nil
@@at_path = nil
diff --git a/activesupport/lib/active_support/i18n.rb b/activesupport/lib/active_support/i18n.rb
index 034d7d8ddc..11af48d67e 100644
--- a/activesupport/lib/active_support/i18n.rb
+++ b/activesupport/lib/active_support/i18n.rb
@@ -1,3 +1,3 @@
require 'i18n'
I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
-ActiveSupport.run_base_hooks(:i18n) \ No newline at end of file
+ActiveSupport.run_load_hooks(:i18n) \ No newline at end of file
diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb
index 36acfda524..642a4c105c 100644
--- a/activesupport/lib/active_support/lazy_load_hooks.rb
+++ b/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -1,25 +1,17 @@
module ActiveSupport
- module LazyLoadHooks
- def _setup_base_hooks
- @base_hooks ||= Hash.new {|h,k| h[k] = [] }
- @base ||= {}
- end
-
- def base_hook(name = nil, &block)
- _setup_base_hooks
+ @load_hooks = Hash.new {|h,k| h[k] = [] }
+ @loaded = {}
- if base = @base[name]
- base.instance_eval(&block)
- else
- @base_hooks[name] << block
- end
+ def self.on_load(name, &block)
+ if base = @loaded[name]
+ base.instance_eval(&block)
+ else
+ @load_hooks[name] << block
end
+ end
- def run_base_hooks(base, name = nil)
- _setup_base_hooks
-
- @base_hooks[name].each { |hook| base.instance_eval(&hook) } if @base_hooks
- @base[name] = base
- end
+ def self.run_load_hooks(name, base = Object)
+ @load_hooks[name].each { |hook| base.instance_eval(&hook) }
+ @loaded[name] = base
end
end \ No newline at end of file
diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb
index e45d16ee96..b8d54ff839 100644
--- a/activesupport/lib/active_support/railtie.rb
+++ b/activesupport/lib/active_support/railtie.rb
@@ -35,7 +35,7 @@ module I18n
config.i18n.load_path = []
initializer "i18n.initialize" do
- ActiveSupport.base_hook(:i18n) do
+ ActiveSupport.on_load(:i18n) do
I18n.reload!
ActionDispatch::Callbacks.to_prepare do
diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb
index c529b92240..33793f0688 100644
--- a/activesupport/lib/active_support/testing/assertions.rb
+++ b/activesupport/lib/active_support/testing/assertions.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/object/blank'
module ActiveSupport
module Testing
@@ -62,6 +63,20 @@ module ActiveSupport
def assert_no_difference(expression, message = nil, &block)
assert_difference expression, 0, message, &block
end
+
+ # Test if an expression is blank. Passes if object.blank? is true.
+ #
+ # assert_blank [] # => true
+ def assert_blank(object)
+ assert object.blank?, "#{object.inspect} is not blank"
+ end
+
+ # Test if an expression is not blank. Passes if object.present? is true.
+ #
+ # assert_present {:data => 'x' } # => true
+ def assert_present(object)
+ assert object.present?, "#{object.inspect} is blank"
+ end
end
end
end
diff --git a/activesupport/lib/active_support/time.rb b/activesupport/lib/active_support/time.rb
index 0f421421d0..784c7173a9 100644
--- a/activesupport/lib/active_support/time.rb
+++ b/activesupport/lib/active_support/time.rb
@@ -14,7 +14,7 @@ require 'date'
require 'time'
require 'active_support/core_ext/time/publicize_conversion_methods'
-require 'active_support/core_ext/time/marshal_with_utc_flag'
+require 'active_support/core_ext/time/marshal'
require 'active_support/core_ext/time/acts_like'
require 'active_support/core_ext/time/calculations'
require 'active_support/core_ext/time/conversions'
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 3cb4d89e02..945cdd5278 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -198,10 +198,12 @@ module ActiveSupport
@name = name
@utc_offset = utc_offset
@tzinfo = tzinfo
+ @current_period = nil
end
def utc_offset
- @utc_offset ||= tzinfo.current_period.utc_offset
+ @current_period ||= tzinfo.current_period
+ @current_period.utc_offset
end
# Returns the offset of this time zone as a formatted string, of the
@@ -362,13 +364,14 @@ module ActiveSupport
"Wellington" ],
[ 46_800, "Nuku'alofa" ]].
each do |offset, *places|
- places.sort.each do |place|
+ places.each do |place|
place.freeze
zone = new(place, offset)
ZONES << zone
ZONES_MAP[place] = zone
end
end
+ ZONES.sort!
ZONES.freeze
ZONES_MAP.freeze
diff --git a/activesupport/lib/active_support/xml_mini/libxmlsax.rb b/activesupport/lib/active_support/xml_mini/libxmlsax.rb
index d7b2f4c5be..fe2c1b9349 100644
--- a/activesupport/lib/active_support/xml_mini/libxmlsax.rb
+++ b/activesupport/lib/active_support/xml_mini/libxmlsax.rb
@@ -1,4 +1,5 @@
require 'libxml'
+require 'active_support/core_ext/object/blank'
# = XmlMini LibXML implementation using a SAX-based parser
module ActiveSupport
diff --git a/activesupport/lib/active_support/xml_mini/nokogirisax.rb b/activesupport/lib/active_support/xml_mini/nokogirisax.rb
index d538a9110f..8af7b5e565 100644
--- a/activesupport/lib/active_support/xml_mini/nokogirisax.rb
+++ b/activesupport/lib/active_support/xml_mini/nokogirisax.rb
@@ -1,4 +1,5 @@
require 'nokogiri'
+require 'active_support/core_ext/object/blank'
# = XmlMini Nokogiri implementation using a SAX-based parser
module ActiveSupport
diff --git a/activesupport/lib/active_support/xml_mini/rexml.rb b/activesupport/lib/active_support/xml_mini/rexml.rb
index 3db48ce5a3..863d66a91d 100644
--- a/activesupport/lib/active_support/xml_mini/rexml.rb
+++ b/activesupport/lib/active_support/xml_mini/rexml.rb
@@ -27,7 +27,13 @@ module ActiveSupport
data.ungetc(char)
silence_warnings { require 'rexml/document' } unless defined?(REXML::Document)
doc = REXML::Document.new(data)
- merge_element!({}, doc.root)
+
+ if doc.root
+ merge_element!({}, doc.root)
+ else
+ raise REXML::ParseException,
+ "The document #{doc.to_s.inspect} does not have a valid root"
+ end
end
end
diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb
index 67f652325e..ea6ebca3ce 100644
--- a/activesupport/test/abstract_unit.rb
+++ b/activesupport/test/abstract_unit.rb
@@ -10,6 +10,7 @@ $:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
require 'test/unit'
require 'active_support/core_ext/kernel/reporting'
+require 'empty_bool'
silence_warnings { require 'mocha' }
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index 00e05f76fe..d96f8e1de5 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -333,6 +333,12 @@ uses_memcached 'memcached backed store' do
assert_equal 'bat', @cache.read('baz')
assert_equal nil, @cache.read('foo')
end
+
+ def test_delete_should_only_pass_key_to_data
+ key = 'foo'
+ @data.expects(:delete).with(key)
+ @cache.delete(key)
+ end
end
class CompressedMemCacheStore < ActiveSupport::TestCase
diff --git a/activesupport/test/core_ext/blank_test.rb b/activesupport/test/core_ext/blank_test.rb
index ed6c625a0a..97c6b213ba 100644
--- a/activesupport/test/core_ext/blank_test.rb
+++ b/activesupport/test/core_ext/blank_test.rb
@@ -1,14 +1,6 @@
require 'abstract_unit'
require 'active_support/core_ext/object/blank'
-class EmptyTrue
- def empty?() true; end
-end
-
-class EmptyFalse
- def empty?() false; end
-end
-
class BlankTest < Test::Unit::TestCase
BLANK = [ EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", [], {} ]
NOT = [ EmptyFalse.new, Object.new, true, 0, 1, 'a', [nil], { nil => 0 } ]
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index 159b7d8366..c24c8619c6 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -758,33 +758,29 @@ end
class TimeExtMarshalingTest < Test::Unit::TestCase
def test_marshaling_with_utc_instance
t = Time.utc(2000)
- marshaled = Marshal.dump t
- unmarshaled = Marshal.load marshaled
- assert_equal t, unmarshaled
+ unmarshaled = Marshal.load(Marshal.dump(t))
assert_equal "UTC", unmarshaled.zone
+ assert_equal t, unmarshaled
end
def test_marshaling_with_local_instance
t = Time.local(2000)
- marshaled = Marshal.dump t
- unmarshaled = Marshal.load marshaled
- assert_equal t, unmarshaled
+ unmarshaled = Marshal.load(Marshal.dump(t))
assert_equal t.zone, unmarshaled.zone
+ assert_equal t, unmarshaled
end
def test_marshaling_with_frozen_utc_instance
t = Time.utc(2000).freeze
- marshaled = Marshal.dump t
- unmarshaled = Marshal.load marshaled
- assert_equal t, unmarshaled
+ unmarshaled = Marshal.load(Marshal.dump(t))
assert_equal "UTC", unmarshaled.zone
+ assert_equal t, unmarshaled
end
def test_marshaling_with_frozen_local_instance
t = Time.local(2000).freeze
- marshaled = Marshal.dump t
- unmarshaled = Marshal.load marshaled
- assert_equal t, unmarshaled
+ unmarshaled = Marshal.load(Marshal.dump(t))
assert_equal t.zone, unmarshaled.zone
+ assert_equal t, unmarshaled
end
end
diff --git a/activesupport/test/empty_bool.rb b/activesupport/test/empty_bool.rb
new file mode 100644
index 0000000000..005b3523ef
--- /dev/null
+++ b/activesupport/test/empty_bool.rb
@@ -0,0 +1,7 @@
+class EmptyTrue
+ def empty?() true; end
+end
+
+class EmptyFalse
+ def empty?() false; end
+end
diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb
index 5c2b44f188..2fba62bdd6 100644
--- a/activesupport/test/message_encryptor_test.rb
+++ b/activesupport/test/message_encryptor_test.rb
@@ -4,7 +4,7 @@ require 'active_support/time'
class MessageEncryptorTest < Test::Unit::TestCase
def setup
@encryptor = ActiveSupport::MessageEncryptor.new(ActiveSupport::SecureRandom.hex(64))
- @data = {:some=>"data", :now=>Time.now}
+ @data = { :some => "data", :now => Time.local(2010) }
end
def test_simple_round_tripping
diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb
index 714a3b3a39..4821311244 100644
--- a/activesupport/test/message_verifier_test.rb
+++ b/activesupport/test/message_verifier_test.rb
@@ -12,7 +12,7 @@ require 'active_support/time'
class MessageVerifierTest < Test::Unit::TestCase
def setup
@verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!")
- @data = {:some=>"data", :now=>Time.now}
+ @data = { :some => "data", :now => Time.local(2010) }
end
def test_simple_round_tripping
diff --git a/activesupport/test/test_test.rb b/activesupport/test/test_test.rb
index 1928da51ca..3092fe01ae 100644
--- a/activesupport/test/test_test.rb
+++ b/activesupport/test/test_test.rb
@@ -86,6 +86,46 @@ class AssertDifferenceTest < ActiveSupport::TestCase
end
end
+class AssertBlankTest < ActiveSupport::TestCase
+ BLANK = [ EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", [], {} ]
+ NOT_BLANK = [ EmptyFalse.new, Object.new, true, 0, 1, 'x', [nil], { nil => 0 } ]
+
+ def test_assert_blank_true
+ BLANK.each { |v| assert_blank v }
+ end
+
+ def test_assert_blank_false
+ NOT_BLANK.each { |v|
+ begin
+ assert_blank v
+ fail 'should not get to here'
+ rescue Exception => e
+ assert_match(/is not blank/, e.message)
+ end
+ }
+ end
+end
+
+class AssertPresentTest < ActiveSupport::TestCase
+ BLANK = [ EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", [], {} ]
+ NOT_BLANK = [ EmptyFalse.new, Object.new, true, 0, 1, 'x', [nil], { nil => 0 } ]
+
+ def test_assert_blank_true
+ NOT_BLANK.each { |v| assert_present v }
+ end
+
+ def test_assert_blank_false
+ BLANK.each { |v|
+ begin
+ assert_present v
+ fail 'should not get to here'
+ rescue Exception => e
+ assert_match(/is blank/, e.message)
+ end
+ }
+ end
+end
+
# These should always pass
if ActiveSupport::Testing.const_defined?(:Default)
class NotTestingThingsTest < Test::Unit::TestCase
diff --git a/ci/ci_build.rb b/ci/ci_build.rb
index 1602c5106d..cd62381d9c 100755
--- a/ci/ci_build.rb
+++ b/ci/ci_build.rb
@@ -19,7 +19,7 @@ puts "[CruiseControl] Rails build"
build_results = {}
# Install required version of bundler.
-bundler_install_cmd = "sudo gem install bundler -v 0.9.10 --no-ri --no-rdoc"
+bundler_install_cmd = "sudo gem install bundler --no-ri --no-rdoc"
puts "Running command: #{bundler_install_cmd}"
build_results[:install_bundler] = system bundler_install_cmd
diff --git a/railties/Rakefile b/railties/Rakefile
index 6368456366..d88036f829 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -1,5 +1,3 @@
-require File.expand_path('../../load_paths', __FILE__)
-
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
@@ -60,10 +58,8 @@ Rake::RDocTask.new { |rdoc|
rdoc.options << '--charset' << 'utf-8'
rdoc.template = ENV['template'] ? "#{ENV['template']}.rb" : '../doc/template/horo'
rdoc.rdoc_files.include('README', 'CHANGELOG')
- rdoc.rdoc_files.include('lib/*.rb')
- rdoc.rdoc_files.include('lib/rails/*.rb')
- rdoc.rdoc_files.include('lib/rails/generators/*.rb')
- rdoc.rdoc_files.include('lib/rails/commands/**/*.rb')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+ rdoc.rdoc_files.exclude('lib/rails/generators/**/templates/*')
}
# Generate GEM ----------------------------------------------------------------------------
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index 5418ad7dd4..55077bcd24 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -9,24 +9,24 @@ endprologue.
h3. Locations for Initialization Code
-Rails offers (at least) five good spots to place initialization code:
+Rails offers (at least) four good spots to place initialization code:
-* Preinitializers
-* environment.rb
+* application.rb
* Environment-specific Configuration Files
* Initializers (load_application_initializers)
* After-Initializers
-h3. Using a Preinitializer
+h3. Running Code Before Rails
-Rails allows you to use a preinitializer to run code before the framework itself is loaded. If you save code in +RAILS_ROOT/config/preinitializer.rb+, that code will be the first thing loaded, before any of the framework components (Active Record, Action Pack, and so on.) If you want to change the behavior of one of the classes that is used in the initialization process, you can do so in this file.
+To run some code before Rails itself is loaded, simply put it above the call to
++require 'rails/all'+ in your +application.rb+.
h3. Configuring Rails Components
-In general, the work of configuring Rails means configuring the components of Rails, as well as configuring Rails itself. The +environment.rb+ and environment-specific configuration files (such as +config/environments/production.rb+) allow you to specify the various settings that you want to pass down to all of the components. For example, the default Rails 2.3 +environment.rb+ file includes one setting:
+In general, the work of configuring Rails means configuring the components of Rails, as well as configuring Rails itself. The +application.rb+ and environment-specific configuration files (such as +config/environments/production.rb+) allow you to specify the various settings that you want to pass down to all of the components. For example, the default Rails 2.3 +application.rb+ file includes one setting:
<ruby>
-config.time_zone = 'UTC'
+config.filter_parameters << :password
</ruby>
This is a setting for Rails itself. If you want to pass settings to individual Rails components, you can do so via the same +config+ object:
@@ -53,8 +53,6 @@ h4. Rails General Configuration
* +config.eager_load_paths+ accepts an array of paths from which Rails will eager load on boot if cache classes is enabled. All elements of this array must also be in +load_paths+.
-* +config.frameworks+ accepts an array of rails framework components that should be loaded. (Defaults to +:active_record+, +:action_controller+, +:action_view+, +:action_mailer+, and +:active_resource+).
-
* +config.load_once_paths+ accepts an array of paths from which Rails will automatically load from only once. All elements of this array must also be in +load_paths+.
* +config.load_paths+ accepts an array of additional paths to prepend to the load path. By default, all app, lib, vendor and mock paths are included in this list.
@@ -133,6 +131,8 @@ h4. Configuring Action Controller
* +config.action_controller.asset_host+ provides a string that is prepended to all of the URL-generating helpers in +AssetHelper+. This is designed to allow moving all javascript, CSS, and image files to a separate asset host.
+* +config.action_controller.asset_path+ allows you to override the default asset path generation by providing your own instructions.
+
* +config.action_controller.consider_all_requests_local+ is generally set to +true+ during development and +false+ during production; if it is set to +true+, then any error will cause detailed debugging information to be dumped in the HTTP response. For finer-grained control, set this to +false+ and implement +local_request?+ to specify which requests should provide debugging information on errors.
* +config.action_controller.allow_concurrency+ should be set to +true+ to allow concurrent (threadsafe) action processing. Set to +false+ by default. You probably don't want to call this one directly, though, because a series of other adjustments need to be made for threadsafe mode to work properly. Instead, you should simply call +config.threadsafe!+ inside your +production.rb+ file, which makes all the necessary adjustments.
diff --git a/railties/lib/rails/application/routes_reloader.rb b/railties/lib/rails/application/routes_reloader.rb
index a5154f4bba..a2b3622df8 100644
--- a/railties/lib/rails/application/routes_reloader.rb
+++ b/railties/lib/rails/application/routes_reloader.rb
@@ -27,7 +27,7 @@ module Rails
routes.clear!
paths.each { |path| load(path) }
- ActionController.base_hook { routes.finalize! }
+ ActiveSupport.on_load(:action_controller) { routes.finalize! }
nil
ensure
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index c57660c0d1..3f74cd49fc 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -54,6 +54,11 @@ module Rails
trap(:INT) { exit }
puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
+ #Create required tmp directories if not found
+ %w(cache pids sessions sockets).each do |dir_to_make|
+ FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make))
+ end
+
super
ensure
# The '-h' option calls exit before @options is set.
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 85cae75bce..e9013348b5 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -180,8 +180,13 @@ module Rails
initializer :add_view_paths do
views = paths.app.views.to_a
- ActionController.base_hook { prepend_view_path(views) } if defined?(ActionController)
- ActionMailer.base_hook { prepend_view_path(views) } if defined?(ActionMailer)
+ ActiveSupport.on_load(:action_controller) do
+ prepend_view_path(views)
+ end
+
+ ActiveSupport.on_load(:action_mailer) do
+ prepend_view_path(views)
+ end
end
initializer :add_metals do |app|
diff --git a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
index a3dc38d9e4..867fc8c985 100644
--- a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
+++ b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
@@ -2,7 +2,7 @@ require 'test_helper'
require 'rails/performance_test_help'
# Profiling results for each test method are written to tmp/performance.
-class BrowsingTest < ActionController::PerformanceTest
+class BrowsingTest < ActionDispatch::PerformanceTest
def test_homepage
get '/'
end
diff --git a/railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb b/railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb
deleted file mode 100644
index 99fd2f45bc..0000000000
--- a/railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Rails
- module Generators
- # TODO Deprecate me in a release > Rails 3.0
- class ModelSubclassGenerator < Base
- desc "model_subclass is deprecated. Invoke model with --parent option instead."
-
- def say_deprecation_warn
- say self.class.desc
- end
- end
- end
-end
diff --git a/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt b/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
index e94c0bfc77..733e321c94 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
@@ -1,10 +1,23 @@
+require 'rake'
require 'rake/testtask'
+require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
desc 'Test the <%= file_name %> plugin.'
Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
end
+
+desc 'Generate documentation for the <%= file_name %> plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = '<%= class_name %>'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb
index 1e78945a7e..8a46708009 100644
--- a/railties/lib/rails/generators/rails/resource/resource_generator.rb
+++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb
@@ -1,5 +1,6 @@
require 'rails/generators/resource_helpers'
require 'rails/generators/rails/model/model_generator'
+require 'active_support/core_ext/object/blank'
module Rails
module Generators
diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake
index f2fee45594..957c375f6a 100644
--- a/railties/lib/rails/tasks/documentation.rake
+++ b/railties/lib/rails/tasks/documentation.rake
@@ -1,4 +1,9 @@
namespace :doc do
+ def gem_path(gem_name)
+ path = $LOAD_PATH.grep(/#{gem_name}[\w.-]*\/lib$/).first
+ yield File.dirname(path) if path
+ end
+
desc "Generate documentation for the application. Set custom template with TEMPLATE=/path/to/rdoc/template.rb or title with TITLE=\"Custom Title\""
Rake::RDocTask.new("app") { |rdoc|
rdoc.rdoc_dir = 'doc/app'
@@ -11,54 +16,56 @@ namespace :doc do
rdoc.rdoc_files.include('lib/**/*.rb')
}
- desc 'Generate documentation for the Rails framework. Specify path with RAILS_PATH="/path/to/rails"'
- path = ENV['RAILS_PATH']
- unless path && File.directory?(path)
- task :rails do
- if path
- $stderr.puts "Skipping doc:rails, missing Rails directory at #{path}"
- else
- $stderr.puts "Skipping doc:rails, RAILS_PATH environment variable is not set"
+ desc 'Generate documentation for the Rails framework.'
+ Rake::RDocTask.new("rails") { |rdoc|
+ rdoc.rdoc_dir = 'doc/api'
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
+ rdoc.title = "Rails Framework Documentation"
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+
+ gem_path('actionmailer') do |actionmailer|
+ %w(README CHANGELOG MIT-LICENSE lib/action_mailer/base.rb).each do |file|
+ rdoc.rdoc_files.include("#{actionmailer}/#{file}")
end
end
- else
- Rake::RDocTask.new("rails") { |rdoc|
- version = "-#{Rails::VERSION::STRING}" unless ENV['RAILS_PATH']
- rdoc.rdoc_dir = 'doc/api'
- rdoc.template = "#{ENV['template']}.rb" if ENV['template']
- rdoc.title = "Rails Framework Documentation"
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
-
- %w(README CHANGELOG lib/action_mailer/base.rb).each do |file|
- rdoc.rdoc_files.include("#{path}/actionmailer#{version}/#{file}")
- end
- %w(README CHANGELOG lib/action_controller/**/*.rb lib/action_view/**/*.rb).each do |file|
- rdoc.rdoc_files.include("#{path}/actionpack#{version}/#{file}")
+ gem_path('actionpack') do |actionpack|
+ %w(README CHANGELOG MIT-LICENSE lib/action_controller/**/*.rb lib/action_view/**/*.rb).each do |file|
+ rdoc.rdoc_files.include("#{actionpack}/#{file}")
end
+ end
- %w(README CHANGELOG lib/active_model/**/*.rb).each do |file|
- rdoc.rdoc_files.include("#{path}/activemodel#{version}/#{file}")
+ gem_path('activemodel') do |activemodel|
+ %w(README CHANGELOG MIT-LICENSE lib/active_model/**/*.rb).each do |file|
+ rdoc.rdoc_files.include("#{activemodel}/#{file}")
end
+ end
+ gem_path('activerecord') do |activerecord|
%w(README CHANGELOG lib/active_record/**/*.rb).each do |file|
- rdoc.rdoc_files.include("#{path}/activerecord#{version}/#{file}")
+ rdoc.rdoc_files.include("#{activerecord}/#{file}")
end
+ end
+ gem_path('activeresource') do |activeresource|
%w(README CHANGELOG lib/active_resource.rb lib/active_resource/*).each do |file|
- rdoc.rdoc_files.include("#{path}/activeresource#{version}/#{file}")
+ rdoc.rdoc_files.include("#{activeresource}/#{file}")
end
+ end
+ gem_path('activesupport') do |activesupport|
%w(README CHANGELOG lib/active_support/**/*.rb).each do |file|
- rdoc.rdoc_files.include("#{path}/activesupport#{version}/#{file}")
+ rdoc.rdoc_files.include("#{activesupport}/#{file}")
end
+ end
- %w(README CHANGELOG MIT-LICENSE lib/{*.rb,commands/*.rb,generators/*.rb}).each do |file|
- rdoc.rdoc_files.include("#{path}/railties#{version}/#{file}")
+ gem_path('railties') do |railties|
+ %w(README CHANGELOG lib/{*.rb,commands/*.rb,generators/*.rb}).each do |file|
+ rdoc.rdoc_files.include("#{railties}/#{file}")
end
- }
- end
+ end
+ }
plugins = FileList['vendor/plugins/**'].collect { |plugin| File.basename(plugin) }
diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb
index 6522c94ad6..3ce4e2c780 100644
--- a/railties/lib/rails/test_help.rb
+++ b/railties/lib/rails/test_help.rb
@@ -30,7 +30,7 @@ end
class ActionController::TestCase
setup do
- @router = Rails.application.routes
+ @routes = Rails.application.routes
end
end
diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb
index 05ec359f61..aa76979c27 100644
--- a/railties/test/rails_info_controller_test.rb
+++ b/railties/test/rails_info_controller_test.rb
@@ -15,9 +15,9 @@ class InfoControllerTest < ActionController::TestCase
match '/rails/info/properties' => "rails/info#properties"
end
@controller.stubs(:consider_all_requests_local? => false, :local_request? => true)
- @router = Rails.application.routes
+ @routes = Rails.application.routes
- Rails::InfoController.send(:include, @router.url_helpers)
+ Rails::InfoController.send(:include, @routes.url_helpers)
end
test "info controller does not allow remote requests" do
diff --git a/tools/console b/tools/console
new file mode 100755
index 0000000000..ea995a1a54
--- /dev/null
+++ b/tools/console
@@ -0,0 +1,7 @@
+#!/usr/bin/env ruby
+require File.expand_path('../../load_paths', __FILE__)
+require 'rails/all'
+require 'active_support/all'
+require 'irb'
+require 'irb/completion'
+IRB.start