aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile6
-rw-r--r--RAILS_VERSION2
-rw-r--r--actionmailer/CHANGELOG.md6
-rw-r--r--actionmailer/actionmailer.gemspec2
-rw-r--r--actionmailer/lib/action_mailer/base.rb3
-rw-r--r--actionmailer/lib/action_mailer/gem_version.rb2
-rw-r--r--actionmailer/lib/action_mailer/mail_helper.rb2
-rw-r--r--actionmailer/test/base_test.rb14
-rw-r--r--actionmailer/test/fixtures/base_test/late_inline_attachment_mailer/on_render.erb7
-rw-r--r--actionpack/actionpack.gemspec4
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb4
-rw-r--r--actionpack/lib/action_pack/gem_version.rb2
-rw-r--r--actionpack/test/controller/new_base/render_file_test.rb29
-rw-r--r--actionpack/test/controller/new_base/render_template_test.rb9
-rw-r--r--actionview/CHANGELOG.md9
-rw-r--r--actionview/actionview.gemspec4
-rw-r--r--actionview/lib/action_view/gem_version.rb2
-rw-r--r--actionview/lib/action_view/helpers/form_helper.rb18
-rw-r--r--actionview/lib/action_view/helpers/url_helper.rb36
-rw-r--r--actionview/lib/action_view/rendering.rb4
-rw-r--r--actionview/lib/action_view/template/resolver.rb7
-rw-r--r--actionview/test/abstract_unit.rb2
-rw-r--r--actionview/test/actionpack/controller/render_test.rb23
-rw-r--r--actionview/test/activerecord/polymorphic_routes_test.rb9
-rw-r--r--activejob/README.md19
-rw-r--r--activejob/lib/active_job/arguments.rb30
-rw-r--r--activejob/lib/active_job/core.rb4
-rw-r--r--activejob/lib/active_job/gem_version.rb2
-rw-r--r--activejob/lib/active_job/queue_adapters.rb34
-rw-r--r--activejob/lib/active_job/queue_adapters/backburner_adapter.rb14
-rw-r--r--activejob/lib/active_job/queue_adapters/delayed_job_adapter.rb26
-rw-r--r--activejob/lib/active_job/queue_adapters/inline_adapter.rb12
-rw-r--r--activejob/lib/active_job/queue_adapters/qu_adapter.rb17
-rw-r--r--activejob/lib/active_job/queue_adapters/que_adapter.rb16
-rw-r--r--activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb20
-rw-r--r--activejob/lib/active_job/queue_adapters/resque_adapter.rb15
-rw-r--r--activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb16
-rw-r--r--activejob/lib/active_job/queue_adapters/sneakers_adapter.rb16
-rw-r--r--activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb19
-rw-r--r--activejob/lib/active_job/queue_adapters/test_adapter.rb13
-rw-r--r--activejob/lib/active_job/test_helper.rb2
-rw-r--r--activejob/test/cases/argument_serialization_test.rb14
-rw-r--r--activejob/test/cases/test_helper_test.rb4
-rw-r--r--activejob/test/support/integration/adapters/delayed_job.rb2
-rw-r--r--activejob/test/support/integration/adapters/que.rb4
-rw-r--r--activejob/test/support/integration/adapters/queue_classic.rb18
-rw-r--r--activejob/test/support/integration/adapters/resque.rb6
-rw-r--r--activejob/test/support/integration/adapters/sidekiq.rb1
-rw-r--r--activejob/test/support/integration/adapters/sucker_punch.rb1
-rw-r--r--activejob/test/support/integration/dummy_app_template.rb2
-rw-r--r--activejob/test/support/integration/helper.rb6
-rw-r--r--activemodel/lib/active_model/gem_version.rb2
-rw-r--r--activemodel/lib/active_model/validations.rb8
-rw-r--r--activemodel/test/cases/validations_test.rb4
-rw-r--r--activerecord/CHANGELOG.md13
-rw-r--r--activerecord/lib/active_record/associations.rb2
-rw-r--r--activerecord/lib/active_record/attribute_set/builder.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb4
-rw-r--r--activerecord/lib/active_record/fixtures.rb2
-rw-r--r--activerecord/lib/active_record/gem_version.rb2
-rw-r--r--activerecord/lib/active_record/querying.rb3
-rw-r--r--activerecord/test/cases/adapters/mysql2/connection_test.rb13
-rw-r--r--activerecord/test/cases/adapters/postgresql/connection_test.rb10
-rw-r--r--activerecord/test/cases/connection_management_test.rb8
-rw-r--r--activerecord/test/cases/fixtures_test.rb2
-rw-r--r--activerecord/test/models/parrot.rb2
-rw-r--r--activesupport/lib/active_support/gem_version.rb2
-rw-r--r--activesupport/test/core_ext/duration_test.rb4
-rwxr-xr-xci/travis.rb1
-rw-r--r--guides/source/4_2_release_notes.md38
-rw-r--r--guides/source/active_job_basics.md42
-rw-r--r--guides/source/configuring.md27
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md17
-rw-r--r--guides/source/upgrading_ruby_on_rails.md17
-rw-r--r--railties/CHANGELOG.md6
-rw-r--r--railties/lib/rails/gem_version.rb2
-rw-r--r--railties/lib/rails/generators/app_base.rb5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/application.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb2
-rw-r--r--railties/lib/rails/info.rb29
-rw-r--r--railties/lib/rails/templates/rails/welcome/index.html.erb28
-rw-r--r--railties/test/application/configuration_test.rb2
-rw-r--r--railties/test/generators/app_generator_test.rb5
-rw-r--r--railties/test/rails_info_test.rb13
-rw-r--r--version.rb2
90 files changed, 563 insertions, 320 deletions
diff --git a/Gemfile b/Gemfile
index 08acdc3767..7df3cc1cfe 100644
--- a/Gemfile
+++ b/Gemfile
@@ -13,12 +13,6 @@ gem 'mocha', '~> 0.14', require: false
gem 'rack-cache', '~> 1.2'
gem 'jquery-rails', '~> 4.0.0.beta2'
gem 'coffee-rails', '~> 4.0.0'
-# TODO: Release this gem
-gem 'rails-html-sanitizer', github: 'rails/rails-html-sanitizer'
-# TODO: Release this gem
-gem 'rails-deprecated_sanitizer', github: 'rails/rails-deprecated_sanitizer'
-# TODO: Release this gem
-gem 'rails-dom-testing', github: 'rails/rails-dom-testing'
gem 'turbolinks', '~> 2.2.3'
# require: false so bcrypt is loaded only when has_secure_password is used.
diff --git a/RAILS_VERSION b/RAILS_VERSION
index e33286503d..a771777d25 100644
--- a/RAILS_VERSION
+++ b/RAILS_VERSION
@@ -1 +1 @@
-4.2.0.beta1
+4.2.0.beta2
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md
index e5e3a0164d..e2900c2d10 100644
--- a/actionmailer/CHANGELOG.md
+++ b/actionmailer/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Attachments can be added while rendering the mail template.
+
+ Fixes #16974.
+
+ *Christian Felder*
+
* Added `#deliver_later`, `#deliver_now` and deprecate `#deliver` in favour of
`#deliver_now`. `#deliver_later` will enqueue a job to render and deliver
the mail instead of delivering it right at that moment. The job is enqueued
diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec
index 089e12ebf1..fbf6c5e9f9 100644
--- a/actionmailer/actionmailer.gemspec
+++ b/actionmailer/actionmailer.gemspec
@@ -24,5 +24,5 @@ Gem::Specification.new do |s|
s.add_dependency 'activejob', version
s.add_dependency 'mail', ['~> 2.5', '>= 2.5.4']
- s.add_dependency 'rails-dom-testing', '~> 1.0', '>= 1.0.2'
+ s.add_dependency 'rails-dom-testing', '~> 1.0', '>= 1.0.3'
end
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index f539fc53c6..1ab68d2953 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -775,7 +775,6 @@ module ActionMailer
def mail(headers = {}, &block)
return @_message if @_mail_was_called && headers.blank? && !block
- @_mail_was_called = true
m = @_message
# At the beginning, do not consider class default for content_type
@@ -803,6 +802,8 @@ module ActionMailer
# Render the templates and blocks
responses = collect_responses(headers, &block)
+ @_mail_was_called = true
+
create_parts_from_responses(m, responses)
# Setup content type, reapply charset and handle parts order
diff --git a/actionmailer/lib/action_mailer/gem_version.rb b/actionmailer/lib/action_mailer/gem_version.rb
index b9162055f7..0c5c55be84 100644
--- a/actionmailer/lib/action_mailer/gem_version.rb
+++ b/actionmailer/lib/action_mailer/gem_version.rb
@@ -8,7 +8,7 @@ module ActionMailer
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/actionmailer/lib/action_mailer/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb
index 483277af04..cc7935a7e0 100644
--- a/actionmailer/lib/action_mailer/mail_helper.rb
+++ b/actionmailer/lib/action_mailer/mail_helper.rb
@@ -29,7 +29,7 @@ module ActionMailer
# Access the message attachments list.
def attachments
- @_message.attachments
+ mailer.attachments
end
# Returns +text+ wrapped at +len+ columns and indented +indent+ spaces.
diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb
index d00f5aea47..dcb6959543 100644
--- a/actionmailer/test/base_test.rb
+++ b/actionmailer/test/base_test.rb
@@ -259,6 +259,20 @@ class BaseTest < ActiveSupport::TestCase
assert_match(/Can't add attachments after `mail` was called./, e.message)
end
+ test "adding inline attachments while rendering mail works" do
+ class LateInlineAttachmentMailer < ActionMailer::Base
+ def on_render
+ mail from: "welcome@example.com", to: "to@example.com"
+ end
+ end
+
+ mail = LateInlineAttachmentMailer.on_render
+ assert_nothing_raised { mail.message }
+
+ assert_equal ["image/jpeg; filename=controller_attachments.jpg",
+ "image/jpeg; filename=attachments.jpg"], mail.attachments.inline.map {|a| a['Content-Type'].to_s }
+ end
+
test "accessing attachments works after mail was called" do
class LateAttachmentAccessorMailer < ActionMailer::Base
def welcome
diff --git a/actionmailer/test/fixtures/base_test/late_inline_attachment_mailer/on_render.erb b/actionmailer/test/fixtures/base_test/late_inline_attachment_mailer/on_render.erb
new file mode 100644
index 0000000000..6decd3bb31
--- /dev/null
+++ b/actionmailer/test/fixtures/base_test/late_inline_attachment_mailer/on_render.erb
@@ -0,0 +1,7 @@
+<h1>Adding an inline image while rendering</h1>
+
+<% controller.attachments.inline["controller_attachments.jpg"] = 'via controller.attachments.inline' %>
+<%= image_tag attachments['controller_attachments.jpg'].url %>
+
+<% attachments.inline["attachments.jpg"] = 'via attachments.inline' %>
+<%= image_tag attachments['attachments.jpg'].url %>
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index c752388e28..69a160fdc8 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -23,8 +23,8 @@ Gem::Specification.new do |s|
s.add_dependency 'rack', '~> 1.6.0.beta'
s.add_dependency 'rack-test', '~> 0.6.2'
- s.add_dependency 'rails-html-sanitizer', '~> 1.0'
- s.add_dependency 'rails-dom-testing', '~> 1.0', '>= 1.0.2'
+ s.add_dependency 'rails-html-sanitizer', '~> 1.0', '>= 1.0.1'
+ s.add_dependency 'rails-dom-testing', '~> 1.0', '>= 1.0.3'
s.add_dependency 'actionview', version
s.add_development_dependency 'activemodel', version
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
index f15868d37e..0847842fa2 100644
--- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
+++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -116,7 +116,6 @@ module ActionDispatch
action,
type,
opts
-
end
# Returns the path component of a URL for the given record. It uses
@@ -159,8 +158,7 @@ module ActionDispatch
end
def polymorphic_path_for_action(action, record_or_hash, options)
- options = options.merge(:action => action, :routing_type => :path)
- polymorphic_path(record_or_hash, options)
+ polymorphic_path(record_or_hash, options.merge(:action => action))
end
class HelperMethodBuilder # :nodoc:
diff --git a/actionpack/lib/action_pack/gem_version.rb b/actionpack/lib/action_pack/gem_version.rb
index 280d35adcb..6834845d4f 100644
--- a/actionpack/lib/action_pack/gem_version.rb
+++ b/actionpack/lib/action_pack/gem_version.rb
@@ -8,7 +8,7 @@ module ActionPack
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/actionpack/test/controller/new_base/render_file_test.rb b/actionpack/test/controller/new_base/render_file_test.rb
index a961cbf849..0c21bb0719 100644
--- a/actionpack/test/controller/new_base/render_file_test.rb
+++ b/actionpack/test/controller/new_base/render_file_test.rb
@@ -13,15 +13,6 @@ module RenderFile
render :file => File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar')
end
- def without_file_key
- render File.join(File.dirname(__FILE__), *%w[.. .. fixtures test hello_world])
- end
-
- def without_file_key_with_instance_variable
- @secret = 'in the sauce'
- render File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar')
- end
-
def relative_path
@secret = 'in the sauce'
render :file => '../../fixtures/test/render_file_with_ivar'
@@ -41,11 +32,6 @@ module RenderFile
path = File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_locals')
render :file => path, :locals => {:secret => 'in the sauce'}
end
-
- def without_file_key_with_locals
- path = FIXTURES.join('test/render_file_with_locals').to_s
- render path, :locals => {:secret => 'in the sauce'}
- end
end
class TestBasic < Rack::TestCase
@@ -61,16 +47,6 @@ module RenderFile
assert_response "The secret is in the sauce\n"
end
- test "rendering path without specifying the :file key" do
- get :without_file_key
- assert_response "Hello world!"
- end
-
- test "rendering path without specifying the :file key with ivar" do
- get :without_file_key_with_instance_variable
- assert_response "The secret is in the sauce\n"
- end
-
test "rendering a relative path" do
get :relative_path
assert_response "The secret is in the sauce\n"
@@ -90,10 +66,5 @@ module RenderFile
get :with_locals
assert_response "The secret is in the sauce\n"
end
-
- test "rendering path without specifying the :file key with locals" do
- get :without_file_key_with_locals
- assert_response "The secret is in the sauce\n"
- end
end
end
diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb
index e87811776a..42a86b1d0d 100644
--- a/actionpack/test/controller/new_base/render_template_test.rb
+++ b/actionpack/test/controller/new_base/render_template_test.rb
@@ -45,6 +45,10 @@ module RenderTemplate
render :template => "locals", :locals => { :secret => 'area51' }
end
+ def with_locals_without_key
+ render "locals", :locals => { :secret => 'area51' }
+ end
+
def builder_template
render :template => "xml_template"
end
@@ -101,6 +105,11 @@ module RenderTemplate
assert_response "The secret is area51"
end
+ test "rendering a template with local variables without key" do
+ get :with_locals
+ assert_response "The secret is area51"
+ end
+
test "rendering a builder template" do
get :builder_template, "format" => "xml"
assert_response "<html>\n <p>Hello</p>\n</html>\n"
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index ed58933472..8ac74dc938 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,3 +1,12 @@
+* Changed the meaning of `render "foo/bar"`.
+
+ Previously, calling `render "foo/bar"` in a controller action is equivalent
+ to `render file: "foo/bar"`. In Rails 4.2, this has been changed to mean
+ `render template: "foo/bar"` instead. If you need to render a file, please
+ change your code to use the explicit form (`render file: "foo/bar"`) instead.
+
+ *Jeremy Jackson*
+
* Add support for ARIA attributes in tags.
Example:
diff --git a/actionview/actionview.gemspec b/actionview/actionview.gemspec
index 69c8326c51..e43c19b018 100644
--- a/actionview/actionview.gemspec
+++ b/actionview/actionview.gemspec
@@ -23,8 +23,8 @@ Gem::Specification.new do |s|
s.add_dependency 'builder', '~> 3.1'
s.add_dependency 'erubis', '~> 2.7.0'
- s.add_dependency 'rails-html-sanitizer', '~> 1.0'
- s.add_dependency 'rails-dom-testing', '~> 1.0', '>= 1.0.2'
+ s.add_dependency 'rails-html-sanitizer', '~> 1.0', '>= 1.0.1'
+ s.add_dependency 'rails-dom-testing', '~> 1.0', '>= 1.0.3'
s.add_development_dependency 'actionpack', version
s.add_development_dependency 'activemodel', version
diff --git a/actionview/lib/action_view/gem_version.rb b/actionview/lib/action_view/gem_version.rb
index 1f506866e9..076b8ec30b 100644
--- a/actionview/lib/action_view/gem_version.rb
+++ b/actionview/lib/action_view/gem_version.rb
@@ -8,7 +8,7 @@ module ActionView
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb
index 09843ca70d..038f9e384b 100644
--- a/actionview/lib/action_view/helpers/form_helper.rb
+++ b/actionview/lib/action_view/helpers/form_helper.rb
@@ -51,9 +51,7 @@ module ActionView
# The HTML generated for this would be (modulus formatting):
#
# <form action="/people" class="new_person" id="new_person" method="post">
- # <div style="display:none">
- # <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
- # </div>
+ # <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
# <label for="person_first_name">First name</label>:
# <input id="person_first_name" name="person[first_name]" type="text" /><br />
#
@@ -81,10 +79,8 @@ module ActionView
# the code above as is would yield instead:
#
# <form action="/people/256" class="edit_person" id="edit_person_256" method="post">
- # <div style="display:none">
- # <input name="_method" type="hidden" value="patch" />
- # <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
- # </div>
+ # <input name="_method" type="hidden" value="patch" />
+ # <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
# <label for="person_first_name">First name</label>:
# <input id="person_first_name" name="person[first_name]" type="text" value="John" /><br />
#
@@ -315,9 +311,7 @@ module ActionView
# The HTML generated for this would be:
#
# <form action='http://www.example.com' method='post' data-remote='true'>
- # <div style='display:none'>
- # <input name='_method' type='hidden' value='patch' />
- # </div>
+ # <input name='_method' type='hidden' value='patch' />
# ...
# </form>
#
@@ -333,9 +327,7 @@ module ActionView
# The HTML generated for this would be:
#
# <form action='http://www.example.com' method='post' data-behavior='autosave' name='go'>
- # <div style='display:none'>
- # <input name='_method' type='hidden' value='patch' />
- # </div>
+ # <input name='_method' type='hidden' value='patch' />
# ...
# </form>
#
diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb
index c3be47133c..364414da05 100644
--- a/actionview/lib/action_view/helpers/url_helper.rb
+++ b/actionview/lib/action_view/helpers/url_helper.rb
@@ -229,59 +229,51 @@ module ActionView
# ==== Examples
# <%= button_to "New", action: "new" %>
# # => "<form method="post" action="/controller/new" class="button_to">
- # # <div><input value="New" type="submit" /></div>
+ # # <input value="New" type="submit" />
# # </form>"
#
# <%= button_to "New", new_articles_path %>
# # => "<form method="post" action="/articles/new" class="button_to">
- # # <div><input value="New" type="submit" /></div>
+ # # <input value="New" type="submit" />
# # </form>"
#
# <%= button_to [:make_happy, @user] do %>
# Make happy <strong><%= @user.name %></strong>
# <% end %>
# # => "<form method="post" action="/users/1/make_happy" class="button_to">
- # # <div>
- # # <button type="submit">
- # # Make happy <strong><%= @user.name %></strong>
- # # </button>
- # # </div>
+ # # <button type="submit">
+ # # Make happy <strong><%= @user.name %></strong>
+ # # </button>
# # </form>"
#
# <%= button_to "New", { action: "new" }, form_class: "new-thing" %>
# # => "<form method="post" action="/controller/new" class="new-thing">
- # # <div><input value="New" type="submit" /></div>
+ # # <input value="New" type="submit" />
# # </form>"
#
#
# <%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
# # => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
- # # <div>
- # # <input value="Create" type="submit" />
- # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
- # # </div>
+ # # <input value="Create" type="submit" />
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# # </form>"
#
#
# <%= button_to "Delete Image", { action: "delete", id: @image.id },
# method: :delete, data: { confirm: "Are you sure?" } %>
# # => "<form method="post" action="/images/delete/1" class="button_to">
- # # <div>
- # # <input type="hidden" name="_method" value="delete" />
- # # <input data-confirm='Are you sure?' value="Delete Image" type="submit" />
- # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
- # # </div>
+ # # <input type="hidden" name="_method" value="delete" />
+ # # <input data-confirm='Are you sure?' value="Delete Image" type="submit" />
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# # </form>"
#
#
# <%= button_to('Destroy', 'http://www.example.com',
# method: "delete", remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
# # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
- # # <div>
- # # <input name='_method' value='delete' type='hidden' />
- # # <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
- # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
- # # </div>
+ # # <input name='_method' value='delete' type='hidden' />
+ # # <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# # </form>"
# #
def button_to(name = nil, options = nil, html_options = nil, &block)
diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb
index 81d5836a8c..5cbdfdf6c0 100644
--- a/actionview/lib/action_view/rendering.rb
+++ b/actionview/lib/action_view/rendering.rb
@@ -108,7 +108,7 @@ module ActionView
end
# Normalize args by converting render "foo" to render :action => "foo" and
- # render "foo/bar" to render :file => "foo/bar".
+ # render "foo/bar" to render :template => "foo/bar".
# :api: private
def _normalize_args(action=nil, options={})
options = super(action, options)
@@ -118,7 +118,7 @@ module ActionView
options = action
when String, Symbol
action = action.to_s
- key = action.include?(?/) ? :file : :action
+ key = action.include?(?/) ? :template : :action
options[key] = action
else
options[:partial] = action
diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb
index d29d020c17..d77421d5f5 100644
--- a/actionview/lib/action_view/template/resolver.rb
+++ b/actionview/lib/action_view/template/resolver.rb
@@ -272,13 +272,13 @@ module ActionView
# Default pattern, loads views the same way as previous versions of rails, eg. when you're
# looking for `users/new` it will produce query glob: `users/new{.{en},}{.{html,js},}{.{erb,haml},}`
#
- # FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}")
+ # FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
#
# This one allows you to keep files with different formats in separate subdirectories,
# eg. `users/new.html` will be loaded from `users/html/new.erb` or `users/new.html.erb`,
# `users/new.js` from `users/js/new.erb` or `users/new.js.erb`, etc.
#
- # FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{.:handlers,}")
+ # FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
#
# If you don't specify a pattern then the default will be used.
#
@@ -287,7 +287,7 @@ module ActionView
#
# ActionController::Base.view_paths = FileSystemResolver.new(
# Rails.root.join("app/views"),
- # ":prefix{/:locale}/:action{.:formats,}{.:handlers,}"
+ # ":prefix{/:locale}/:action{.:formats,}{+:variants,}{.:handlers,}"
# )
#
# ==== Pattern format and variables
@@ -299,6 +299,7 @@ module ActionView
# * <tt>:action</tt> - name of the action
# * <tt>:locale</tt> - possible locale versions
# * <tt>:formats</tt> - possible request formats (for example html, json, xml...)
+ # * <tt>:variants</tt> - possible request variants (for example phone, tablet...)
# * <tt>:handlers</tt> - possible handlers (for example erb, haml, builder...)
#
class FileSystemResolver < PathResolver
diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb
index e51461d82c..7096d588b6 100644
--- a/actionview/test/abstract_unit.rb
+++ b/actionview/test/abstract_unit.rb
@@ -16,11 +16,9 @@ silence_warnings do
end
require 'active_support/testing/autorun'
-require 'abstract_controller'
require 'action_controller'
require 'action_view'
require 'action_view/testing/resolvers'
-require 'action_dispatch'
require 'active_support/dependencies'
require 'active_model'
require 'active_record'
diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb
index b3b51ae583..563caee8a2 100644
--- a/actionview/test/actionpack/controller/render_test.rb
+++ b/actionview/test/actionpack/controller/render_test.rb
@@ -91,17 +91,17 @@ class TestController < ApplicationController
# :ported:
def render_hello_world
- render :template => "test/hello_world"
+ render "test/hello_world"
end
def render_hello_world_with_last_modified_set
response.last_modified = Date.new(2008, 10, 10).to_time
- render :template => "test/hello_world"
+ render "test/hello_world"
end
# :ported: compatibility
def render_hello_world_with_forward_slash
- render :template => "/test/hello_world"
+ render "/test/hello_world"
end
# :ported:
@@ -111,7 +111,7 @@ class TestController < ApplicationController
# :deprecated:
def render_template_in_top_directory_with_slash
- render :template => '/shared'
+ render '/shared'
end
# :ported:
@@ -160,13 +160,6 @@ class TestController < ApplicationController
end
# :ported:
- def render_file_as_string_with_instance_variables
- @secret = 'in the sauce'
- path = File.expand_path(File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar'))
- render path
- end
-
- # :ported:
def render_file_not_using_full_path
@secret = 'in the sauce'
render :file => 'test/render_file_with_ivar'
@@ -194,7 +187,7 @@ class TestController < ApplicationController
def render_file_as_string_with_locals
path = File.expand_path(File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_locals'))
- render path, :locals => {:secret => 'in the sauce'}
+ render file: path, :locals => {:secret => 'in the sauce'}
end
def accessing_request_in_template
@@ -794,12 +787,6 @@ class RenderTest < ActionController::TestCase
end
# :ported:
- def test_render_file_as_string_with_instance_variables
- get :render_file_as_string_with_instance_variables
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- # :ported:
def test_render_file_not_using_full_path
get :render_file_not_using_full_path
assert_equal "The secret is in the sauce\n", @response.body
diff --git a/actionview/test/activerecord/polymorphic_routes_test.rb b/actionview/test/activerecord/polymorphic_routes_test.rb
index 4e94304796..5842b775bb 100644
--- a/actionview/test/activerecord/polymorphic_routes_test.rb
+++ b/actionview/test/activerecord/polymorphic_routes_test.rb
@@ -282,6 +282,15 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
end
+ def test_regression_path_helper_prefixed_with_new_and_edit
+ with_test_routes do
+ assert_equal "/projects/new", new_polymorphic_path(@project)
+
+ @project.save
+ assert_equal "/projects/#{@project.id}/edit", edit_polymorphic_path(@project)
+ end
+ end
+
def test_url_helper_prefixed_with_edit
with_test_routes do
@project.save
diff --git a/activejob/README.md b/activejob/README.md
index 5734ca413e..b5d27272b1 100644
--- a/activejob/README.md
+++ b/activejob/README.md
@@ -24,9 +24,9 @@ Set the queue adapter for Active Job:
``` ruby
ActiveJob::Base.queue_adapter = :inline # default queue adapter
-# Adapters currently supported: :backburner, :delayed_job, :qu, :que, :queue_classic,
-# :resque, :sidekiq, :sneakers, :sucker_punch
```
+Note: To learn how to use your preferred queueing backend see its adapter
+documentation at ActiveJob::QueueAdapters.
Declare a job like so:
@@ -88,18 +88,9 @@ by default has been mixed into Active Record classes.
## Supported queueing systems
-We currently have adapters for:
-
-* [Backburner](https://github.com/nesquena/backburner)
-* [Delayed Job](https://github.com/collectiveidea/delayed_job)
-* [Qu](https://github.com/bkeepers/qu)
-* [Que](https://github.com/chanks/que)
-* [QueueClassic](https://github.com/ryandotsmith/queue_classic)
-* [Resque 1.x](https://github.com/resque/resque)
-* [Sidekiq](https://github.com/mperham/sidekiq)
-* [Sneakers](https://github.com/jondot/sneakers)
-* [Sucker Punch](https://github.com/brandonhilkert/sucker_punch)
-
+Active Job has built-in adapters for multiple queueing backends (Sidekiq,
+Resque, Delayed Job and others). To get an up-to-date list of the adapters
+see the API Documentation for [ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
## Auxiliary gems
diff --git a/activejob/lib/active_job/arguments.rb b/activejob/lib/active_job/arguments.rb
index 099ea4d169..86b85ebdba 100644
--- a/activejob/lib/active_job/arguments.rb
+++ b/activejob/lib/active_job/arguments.rb
@@ -35,12 +35,15 @@ module ActiveJob
end
private
+ GLOBALID_KEY = '_aj_globalid'.freeze
+ private_constant :GLOBALID_KEY
+
def serialize_argument(argument)
case argument
when *TYPE_WHITELIST
argument
when GlobalID::Identification
- argument.to_global_id.to_s
+ { GLOBALID_KEY => argument.to_global_id.to_s }
when Array
argument.map { |arg| serialize_argument(arg) }
when Hash
@@ -61,16 +64,37 @@ module ActiveJob
when Array
argument.map { |arg| deserialize_argument(arg) }
when Hash
- argument.each_with_object({}.with_indifferent_access) do |(key, value), hash|
- hash[key] = deserialize_argument(value)
+ if serialized_global_id?(argument)
+ deserialize_global_id argument
+ else
+ deserialize_hash argument
end
else
raise ArgumentError, "Can only deserialize primitive arguments: #{argument.inspect}"
end
end
+ def serialized_global_id?(hash)
+ hash.size == 1 and hash.include?(GLOBALID_KEY)
+ end
+
+ def deserialize_global_id(hash)
+ GlobalID::Locator.locate hash[GLOBALID_KEY]
+ end
+
+ def deserialize_hash(serialized_hash)
+ serialized_hash.each_with_object({}.with_indifferent_access) do |(key, value), hash|
+ hash[key] = deserialize_argument(value)
+ end
+ end
+
+ RESERVED_KEYS = [GLOBALID_KEY, GLOBALID_KEY.to_sym]
+ private_constant :RESERVED_KEYS
+
def serialize_hash_key(key)
case key
+ when *RESERVED_KEYS
+ raise SerializationError.new("Can't serialize a Hash with reserved key #{key.inspect}")
when String, Symbol
key.to_s
else
diff --git a/activejob/lib/active_job/core.rb b/activejob/lib/active_job/core.rb
index 9db23cc9da..f55db5a588 100644
--- a/activejob/lib/active_job/core.rb
+++ b/activejob/lib/active_job/core.rb
@@ -40,9 +40,9 @@ module ActiveJob
#
# VideoJob.set(queue: :some_queue).perform_later(Video.last)
# VideoJob.set(wait: 5.minutes).perform_later(Video.last)
- # VideoJob.set(wait_until: Time.tomorroe).perform_later(Video.last)
+ # VideoJob.set(wait_until: Time.now.tomorrow).perform_later(Video.last)
# VideoJob.set(queue: :some_queue, wait: 5.minutes).perform_later(Video.last)
- # VideoJob.set(queue: :some_queue, wait_until: Time.tomorroe).perform_later(Video.last)
+ # VideoJob.set(queue: :some_queue, wait_until: Time.now.tomorrow).perform_later(Video.last)
def set(options={})
ConfiguredJob.new(self, options)
end
diff --git a/activejob/lib/active_job/gem_version.rb b/activejob/lib/active_job/gem_version.rb
index 1f25d48326..f80e6563b8 100644
--- a/activejob/lib/active_job/gem_version.rb
+++ b/activejob/lib/active_job/gem_version.rb
@@ -8,7 +8,7 @@ module ActiveJob
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/activejob/lib/active_job/queue_adapters.rb b/activejob/lib/active_job/queue_adapters.rb
index 345b01ef00..e865c901ce 100644
--- a/activejob/lib/active_job/queue_adapters.rb
+++ b/activejob/lib/active_job/queue_adapters.rb
@@ -1,4 +1,38 @@
module ActiveJob
+ # == Active Job adapters
+ #
+ # Active Job has adapters for the following queueing backends:
+ #
+ # * {Backburner}[https://github.com/nesquena/backburner]
+ # * {Delayed Job}[https://github.com/collectiveidea/delayed_job]
+ # * {Qu}[https://github.com/bkeepers/qu]
+ # * {Que}[https://github.com/chanks/que]
+ # * {QueueClassic 2.x}[https://github.com/ryandotsmith/queue_classic/tree/v2.2.3]
+ # * {Resque 1.x}[https://github.com/resque/resque/tree/1-x-stable]
+ # * {Sidekiq}[http://sidekiq.org]
+ # * {Sneakers}[https://github.com/jondot/sneakers]
+ # * {Sucker Punch}[https://github.com/brandonhilkert/sucker_punch]
+ #
+ # #### Backends Features
+ #
+ # | | Async | Queues | Delayed | Priorities | Timeout | Retries |
+ # |-------------------|-------|--------|-----------|------------|---------|---------|
+ # | Backburner | Yes | Yes | Yes | Yes | Job | Global |
+ # | Delayed Job | Yes | Yes | Yes | Job | Global | Global |
+ # | Que | Yes | Yes | Yes | Job | No | Job |
+ # | Queue Classic | Yes | Yes | No* | No | No | No |
+ # | Resque | Yes | Yes | Yes (Gem) | Queue | Global | Yes |
+ # | Sidekiq | Yes | Yes | Yes | Queue | No | Job |
+ # | Sneakers | Yes | Yes | No | Queue | Queue | No |
+ # | Sucker Punch | Yes | Yes | No | No | No | No |
+ # | Active Job Inline | No | Yes | N/A | N/A | N/A | N/A |
+ # | Active Job | Yes | Yes | Yes | No | No | No |
+ #
+ # NOTE:
+ # Queue Classic does not support Job scheduling. However you can implement this
+ # yourself or you can use the queue_classic-later gem. See the documentation for
+ # ActiveJob::QueueAdapters::QueueClassicAdapter.
+ #
module QueueAdapters
extend ActiveSupport::Autoload
diff --git a/activejob/lib/active_job/queue_adapters/backburner_adapter.rb b/activejob/lib/active_job/queue_adapters/backburner_adapter.rb
index a07a6fc223..2453d065de 100644
--- a/activejob/lib/active_job/queue_adapters/backburner_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/backburner_adapter.rb
@@ -2,13 +2,23 @@ require 'backburner'
module ActiveJob
module QueueAdapters
+ # == Backburner adapter for Active Job
+ #
+ # Backburner is a beanstalkd-powered job queue that can handle a very
+ # high volume of jobs. You create background jobs and place them on
+ # multiple work queues to be processed later. Read more about
+ # Backburner {here}[https://github.com/nesquena/backburner].
+ #
+ # To use Backburner set the queue_adapter config to +:backburner+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :backburner
class BackburnerAdapter
class << self
- def enqueue(job)
+ def enqueue(job) #:nodoc:
Backburner::Worker.enqueue JobWrapper, [ job.serialize ], queue: job.queue_name
end
- def enqueue_at(job, timestamp)
+ def enqueue_at(job, timestamp) #:nodoc:
delay = timestamp - Time.current.to_f
Backburner::Worker.enqueue JobWrapper, [ job.serialize ], queue: job.queue_name, delay: delay
end
diff --git a/activejob/lib/active_job/queue_adapters/delayed_job_adapter.rb b/activejob/lib/active_job/queue_adapters/delayed_job_adapter.rb
index 30c535f3b4..4d27c4fff8 100644
--- a/activejob/lib/active_job/queue_adapters/delayed_job_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/delayed_job_adapter.rb
@@ -2,19 +2,35 @@ require 'delayed_job'
module ActiveJob
module QueueAdapters
+ # == Delayed Job adapter for Active Job
+ #
+ # Delayed::Job (or DJ) encapsulates the common pattern of asynchronously
+ # executing longer tasks in the background. Although DJ can have many
+ # storage backends one of the most used is based on Active Record.
+ # Read more about Delayed Job {here}[https://github.com/collectiveidea/delayed_job].
+ #
+ # To use Delayed Job set the queue_adapter config to +:delayed_job+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :delayed_job
class DelayedJobAdapter
class << self
- def enqueue(job)
- JobWrapper.new.delay(queue: job.queue_name).perform(job.serialize)
+ def enqueue(job) #:nodoc:
+ Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name)
end
- def enqueue_at(job, timestamp)
- JobWrapper.new.delay(queue: job.queue_name, run_at: Time.at(timestamp)).perform(job.serialize)
+ def enqueue_at(job, timestamp) #:nodoc:
+ Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name, run_at: Time.at(timestamp))
end
end
class JobWrapper #:nodoc:
- def perform(job_data)
+ attr_accessor :job_data
+
+ def initialize(job_data)
+ @job_data = job_data
+ end
+
+ def perform
Base.execute(job_data)
end
end
diff --git a/activejob/lib/active_job/queue_adapters/inline_adapter.rb b/activejob/lib/active_job/queue_adapters/inline_adapter.rb
index fdefa38d5e..e498454909 100644
--- a/activejob/lib/active_job/queue_adapters/inline_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/inline_adapter.rb
@@ -1,12 +1,20 @@
module ActiveJob
module QueueAdapters
+ # == Active Job Inline adapter
+ #
+ # When enqueueing jobs with the Inline adapter the job will be executed
+ # immediately.
+ #
+ # To use the Inline set the queue_adapter config to +:inline+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :inline
class InlineAdapter
class << self
- def enqueue(job)
+ def enqueue(job) #:nodoc:
Base.execute(job.serialize)
end
- def enqueue_at(*)
+ def enqueue_at(*) #:nodoc:
raise NotImplementedError.new("Use a queueing backend to enqueue jobs in the future. Read more at https://github.com/rails/activejob")
end
end
diff --git a/activejob/lib/active_job/queue_adapters/qu_adapter.rb b/activejob/lib/active_job/queue_adapters/qu_adapter.rb
index 5485f20689..30aa5a4670 100644
--- a/activejob/lib/active_job/queue_adapters/qu_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/qu_adapter.rb
@@ -2,15 +2,28 @@ require 'qu'
module ActiveJob
module QueueAdapters
+ # == Qu adapter for Active Job
+ #
+ # Qu is a Ruby library for queuing and processing background jobs. It is
+ # heavily inspired by delayed_job and Resque. Qu was created to overcome
+ # some shortcomings in the existing queuing libraries.
+ # The advantages of Qu are: Multiple backends (redis, mongo), jobs are
+ # requeued when worker is killed, resque-like API.
+ #
+ # Read more about Qu {here}[https://github.com/bkeepers/qu].
+ #
+ # To use Qu set the queue_adapter config to +:qu+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :qu
class QuAdapter
class << self
- def enqueue(job, *args)
+ def enqueue(job, *args) #:nodoc:
Qu::Payload.new(klass: JobWrapper, args: [job.serialize]).tap do |payload|
payload.instance_variable_set(:@queue, job.queue_name)
end.push
end
- def enqueue_at(job, timestamp, *args)
+ def enqueue_at(job, timestamp, *args) #:nodoc:
raise NotImplementedError
end
end
diff --git a/activejob/lib/active_job/queue_adapters/que_adapter.rb b/activejob/lib/active_job/queue_adapters/que_adapter.rb
index 2e8a64aa87..e501fe0368 100644
--- a/activejob/lib/active_job/queue_adapters/que_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/que_adapter.rb
@@ -2,13 +2,25 @@ require 'que'
module ActiveJob
module QueueAdapters
+ # == Que adapter for Active Job
+ #
+ # Que is a high-performance alternative to DelayedJob or QueueClassic that
+ # improves the reliability of your application by protecting your jobs with
+ # the same ACID guarantees as the rest of your data. Que is a queue for
+ # Ruby and PostgreSQL that manages jobs using advisory locks.
+ #
+ # Read more about Que {here}[https://github.com/chanks/que].
+ #
+ # To use Que set the queue_adapter config to +:que+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :que
class QueAdapter
class << self
- def enqueue(job)
+ def enqueue(job) #:nodoc:
JobWrapper.enqueue job.serialize, queue: job.queue_name
end
- def enqueue_at(job, timestamp)
+ def enqueue_at(job, timestamp) #:nodoc:
JobWrapper.enqueue job.serialize, queue: job.queue_name, run_at: Time.at(timestamp)
end
end
diff --git a/activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb b/activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb
index e8452938b8..f160932578 100644
--- a/activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb
@@ -2,13 +2,27 @@ require 'queue_classic'
module ActiveJob
module QueueAdapters
+ # == Queue Classic adapter for Active Job
+ #
+ # queue_classic provides a simple interface to a PostgreSQL-backed message
+ # queue. queue_classic specializes in concurrent locking and minimizing
+ # database load while providing a simple, intuitive developer experience.
+ # queue_classic assumes that you are already using PostgreSQL in your
+ # production environment and that adding another dependency (e.g. redis,
+ # beanstalkd, 0mq) is undesirable.
+ #
+ # Read more about Queue Classic {here}[https://github.com/ryandotsmith/queue_classic].
+ #
+ # To use Queue Classic set the queue_adapter config to +:queue_classic+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :queue_classic
class QueueClassicAdapter
class << self
- def enqueue(job)
+ def enqueue(job) #:nodoc:
build_queue(job.queue_name).enqueue("#{JobWrapper.name}.perform", job.serialize)
end
- def enqueue_at(job, timestamp)
+ def enqueue_at(job, timestamp) #:nodoc:
queue = build_queue(job.queue_name)
unless queue.respond_to?(:enqueue_at)
raise NotImplementedError, 'To be able to schedule jobs with Queue Classic ' \
@@ -20,7 +34,7 @@ module ActiveJob
# Builds a <tt>QC::Queue</tt> object to schedule jobs on.
#
- # If you have a custom <tt>QC::Queue</tt> subclass you'll need to suclass
+ # If you have a custom <tt>QC::Queue</tt> subclass you'll need to subclass
# <tt>ActiveJob::QueueAdapters::QueueClassicAdapter</tt> and override the
# <tt>build_queue</tt> method.
def build_queue(queue_name)
diff --git a/activejob/lib/active_job/queue_adapters/resque_adapter.rb b/activejob/lib/active_job/queue_adapters/resque_adapter.rb
index b1bc2f15ee..88c6b48fef 100644
--- a/activejob/lib/active_job/queue_adapters/resque_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/resque_adapter.rb
@@ -14,13 +14,24 @@ end
module ActiveJob
module QueueAdapters
+ # == Resque adapter for Active Job
+ #
+ # Resque (pronounced like "rescue") is a Redis-backed library for creating
+ # background jobs, placing those jobs on multiple queues, and processing
+ # them later.
+ #
+ # Read more about Resque {here}[https://github.com/resque/resque].
+ #
+ # To use Resque set the queue_adapter config to +:resque+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :resque
class ResqueAdapter
class << self
- def enqueue(job)
+ def enqueue(job) #:nodoc:
Resque.enqueue_to job.queue_name, JobWrapper, job.serialize
end
- def enqueue_at(job, timestamp)
+ def enqueue_at(job, timestamp) #:nodoc:
unless Resque.respond_to?(:enqueue_at_with_queue)
raise NotImplementedError, "To be able to schedule jobs with Resque you need the " \
"resque-scheduler gem. Please add it to your Gemfile and run bundle install"
diff --git a/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb b/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb
index 6d351172de..7d80a6fd7a 100644
--- a/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb
@@ -2,9 +2,21 @@ require 'sidekiq'
module ActiveJob
module QueueAdapters
+ # == Sidekiq adapter for Active Job
+ #
+ # Simple, efficient background processing for Ruby. Sidekiq uses threads to
+ # handle many jobs at the same time in the same process. It does not
+ # require Rails but will integrate tightly with it to make background
+ # processing dead simple.
+ #
+ # Read more about Sidekiq {here}[http://sidekiq.org].
+ #
+ # To use Sidekiq set the queue_adapter config to +:sidekiq+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :sidekiq
class SidekiqAdapter
class << self
- def enqueue(job)
+ def enqueue(job) #:nodoc:
#Sidekiq::Client does not support symbols as keys
Sidekiq::Client.push \
'class' => JobWrapper,
@@ -13,7 +25,7 @@ module ActiveJob
'retry' => true
end
- def enqueue_at(job, timestamp)
+ def enqueue_at(job, timestamp) #:nodoc:
Sidekiq::Client.push \
'class' => JobWrapper,
'queue' => job.queue_name,
diff --git a/activejob/lib/active_job/queue_adapters/sneakers_adapter.rb b/activejob/lib/active_job/queue_adapters/sneakers_adapter.rb
index 91658e08f0..6d60a2f303 100644
--- a/activejob/lib/active_job/queue_adapters/sneakers_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/sneakers_adapter.rb
@@ -3,18 +3,30 @@ require 'thread'
module ActiveJob
module QueueAdapters
+ # == Sneakers adapter for Active Job
+ #
+ # A high-performance RabbitMQ background processing framework for Ruby.
+ # Sneakers is being used in production for both I/O and CPU intensive
+ # workloads, and have achieved the goals of high-performance and
+ # 0-maintenance, as designed.
+ #
+ # Read more about Sneakers {here}[https://github.com/jondot/sneakers].
+ #
+ # To use Sneakers set the queue_adapter config to +:sneakers+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :sneakers
class SneakersAdapter
@monitor = Monitor.new
class << self
- def enqueue(job)
+ def enqueue(job) #:nodoc:
@monitor.synchronize do
JobWrapper.from_queue job.queue_name
JobWrapper.enqueue ActiveSupport::JSON.encode(job.serialize)
end
end
- def enqueue_at(job, timestamp)
+ def enqueue_at(job, timestamp) #:nodoc:
raise NotImplementedError
end
end
diff --git a/activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb b/activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb
index 68aa58cadb..be9e7fd03a 100644
--- a/activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb
@@ -2,13 +2,28 @@ require 'sucker_punch'
module ActiveJob
module QueueAdapters
+ # == Sucker Punch adapter for Active Job
+ #
+ # Sucker Punch is a single-process Ruby asynchronous processing library.
+ # It's girl_friday and DSL sugar on top of Celluloid. With Celluloid's
+ # actor pattern, we can do asynchronous processing within a single process.
+ # This reduces costs of hosting on a service like Heroku along with the
+ # memory footprint of having to maintain additional jobs if hosting on
+ # a dedicated server. All queues can run within a single Rails/Sinatra
+ # process.
+ #
+ # Read more about Sucker Punch {here}[https://github.com/brandonhilkert/sucker_punch].
+ #
+ # To use Sucker Punch set the queue_adapter config to +:sucker_punch+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :sucker_punch
class SuckerPunchAdapter
class << self
- def enqueue(job)
+ def enqueue(job) #:nodoc:
JobWrapper.new.async.perform job.serialize
end
- def enqueue_at(job, timestamp)
+ def enqueue_at(job, timestamp) #:nodoc:
raise NotImplementedError
end
end
diff --git a/activejob/lib/active_job/queue_adapters/test_adapter.rb b/activejob/lib/active_job/queue_adapters/test_adapter.rb
index 12ef72310d..e4fdf60008 100644
--- a/activejob/lib/active_job/queue_adapters/test_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/test_adapter.rb
@@ -1,5 +1,14 @@
module ActiveJob
module QueueAdapters
+ # == Test adapter for Active Job
+ #
+ # The test adapter should be used only in testing. Along with
+ # <tt>ActiveJob::TestCase</tt> and <tt>ActiveJob::TestHelper</tt>
+ # it makes a great tool to test your Rails application.
+ #
+ # To use the test adapter set queue_adapter config to +:test+.
+ #
+ # Rails.application.config.active_job.queue_adapter = :test
class TestAdapter
delegate :name, to: :class
attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs)
@@ -15,7 +24,7 @@ module ActiveJob
@performed_jobs ||= []
end
- def enqueue(job)
+ def enqueue(job) #:nodoc:
if perform_enqueued_jobs
performed_jobs << {job: job.class, args: job.arguments, queue: job.queue_name}
job.perform_now
@@ -24,7 +33,7 @@ module ActiveJob
end
end
- def enqueue_at(job, timestamp)
+ def enqueue_at(job, timestamp) #:nodoc:
if perform_enqueued_at_jobs
performed_jobs << {job: job.class, args: job.arguments, queue: job.queue_name, at: timestamp}
job.perform_now
diff --git a/activejob/lib/active_job/test_helper.rb b/activejob/lib/active_job/test_helper.rb
index fa0576669e..af62fae9b9 100644
--- a/activejob/lib/active_job/test_helper.rb
+++ b/activejob/lib/active_job/test_helper.rb
@@ -150,7 +150,7 @@ module ActiveJob
matching_job = enqueued_jobs.any? do |job|
args.all? { |key, value| value == job[key] }
end
- assert matching_job
+ assert matching_job, "No enqueued job found with #{args}"
ensure
queue_adapter.enqueued_jobs = original_enqueued_jobs + enqueued_jobs
end
diff --git a/activejob/test/cases/argument_serialization_test.rb b/activejob/test/cases/argument_serialization_test.rb
index 5a46c5cdef..dbe36fc572 100644
--- a/activejob/test/cases/argument_serialization_test.rb
+++ b/activejob/test/cases/argument_serialization_test.rb
@@ -31,12 +31,12 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
end
test 'should convert records to Global IDs' do
- assert_arguments_roundtrip [@person], [@person.to_gid.to_s]
+ assert_arguments_roundtrip [@person], ['_aj_globalid' => @person.to_gid.to_s]
end
test 'should dive deep into arrays and hashes' do
- assert_arguments_roundtrip [3, [@person]], [3, [@person.to_gid.to_s]]
- assert_arguments_roundtrip [{ 'a' => @person }], [{ 'a' => @person.to_gid.to_s }.with_indifferent_access]
+ assert_arguments_roundtrip [3, [@person]], [3, ['_aj_globalid' => @person.to_gid.to_s]]
+ assert_arguments_roundtrip [{ 'a' => @person }], [{ 'a' => { '_aj_globalid' => @person.to_gid.to_s }}.with_indifferent_access]
end
test 'should stringify symbol hash keys' do
@@ -51,6 +51,14 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
assert_raises ActiveJob::SerializationError do
ActiveJob::Arguments.serialize [ { :a => [{ 2 => 3 }] } ]
end
+
+ assert_raises ActiveJob::SerializationError do
+ ActiveJob::Arguments.serialize [ '_aj_globalid' => 1 ]
+ end
+
+ assert_raises ActiveJob::SerializationError do
+ ActiveJob::Arguments.serialize [ :_aj_globalid => 1 ]
+ end
end
test 'should not allow non-primitive objects' do
diff --git a/activejob/test/cases/test_helper_test.rb b/activejob/test/cases/test_helper_test.rb
index eab540bb6c..71c505a65f 100644
--- a/activejob/test/cases/test_helper_test.rb
+++ b/activejob/test/cases/test_helper_test.rb
@@ -97,11 +97,13 @@ class EnqueuedJobsTest < ActiveJob::TestCase
end
end
- assert_raise ActiveSupport::TestCase::Assertion do
+ error = assert_raise ActiveSupport::TestCase::Assertion do
assert_enqueued_with(job: NestedJob, queue: 'low') do
NestedJob.perform_later
end
end
+
+ assert_equal 'No enqueued job found with {:job=>NestedJob, :queue=>"low"}', error.message
end
def test_assert_enqueued_job_args
diff --git a/activejob/test/support/integration/adapters/delayed_job.rb b/activejob/test/support/integration/adapters/delayed_job.rb
index dbd0d1a4db..0b591964bc 100644
--- a/activejob/test/support/integration/adapters/delayed_job.rb
+++ b/activejob/test/support/integration/adapters/delayed_job.rb
@@ -10,7 +10,7 @@ module DelayedJobJobsManager
end
def start_workers
- @worker = Delayed::Worker.new(quiet: false, sleep_delay: 0.5, queues: %w(integration_tests))
+ @worker = Delayed::Worker.new(quiet: true, sleep_delay: 0.5, queues: %w(integration_tests))
@thread = Thread.new { @worker.start }
end
diff --git a/activejob/test/support/integration/adapters/que.rb b/activejob/test/support/integration/adapters/que.rb
index a5b9b3ec0a..ba7657a42a 100644
--- a/activejob/test/support/integration/adapters/que.rb
+++ b/activejob/test/support/integration/adapters/que.rb
@@ -2,12 +2,12 @@ module QueJobsManager
def setup
require 'sequel'
ActiveJob::Base.queue_adapter = :que
- que_url = ENV['QUE_DATABASE_URL'] || 'postgres://localhost/active_jobs_que_int_test'
+ que_url = ENV['QUE_DATABASE_URL'] || 'postgres:///active_jobs_que_int_test'
uri = URI.parse(que_url)
user = uri.user||ENV['USER']
pass = uri.password
db = uri.path[1..-1]
- %x{#{"PGPASSWORD=\"#{pass}\"" if pass} psql -c 'drop database "#{db}"' -U #{user} -t template1}
+ %x{#{"PGPASSWORD=\"#{pass}\"" if pass} psql -c 'drop database if exists "#{db}"' -U #{user} -t template1}
%x{#{"PGPASSWORD=\"#{pass}\"" if pass} psql -c 'create database "#{db}"' -U #{user} -t template1}
Que.connection = Sequel.connect(que_url)
Que.migrate!
diff --git a/activejob/test/support/integration/adapters/queue_classic.rb b/activejob/test/support/integration/adapters/queue_classic.rb
index 81d1935132..038473ccdc 100644
--- a/activejob/test/support/integration/adapters/queue_classic.rb
+++ b/activejob/test/support/integration/adapters/queue_classic.rb
@@ -1,12 +1,12 @@
module QueueClassicJobsManager
def setup
- ENV['QC_DATABASE_URL'] ||= 'postgres://localhost/active_jobs_qc_int_test'
+ ENV['QC_DATABASE_URL'] ||= 'postgres:///active_jobs_qc_int_test'
ENV['QC_LISTEN_TIME'] = "0.5"
uri = URI.parse(ENV['QC_DATABASE_URL'])
user = uri.user||ENV['USER']
pass = uri.password
db = uri.path[1..-1]
- %x{#{"PGPASSWORD=\"#{pass}\"" if pass} psql -c 'drop database "#{db}"' -U #{user} -t template1}
+ %x{#{"PGPASSWORD=\"#{pass}\"" if pass} psql -c 'drop database if exists "#{db}"' -U #{user} -t template1}
%x{#{"PGPASSWORD=\"#{pass}\"" if pass} psql -c 'create database "#{db}"' -U #{user} -t template1}
ActiveJob::Base.queue_adapter = :queue_classic
QC::Setup.create
@@ -17,23 +17,11 @@ module QueueClassicJobsManager
def clear_jobs
QC::Queue.new("integration_tests").delete_all
- retried = false
- rescue => e
- puts "Got exception while trying to clear jobs: #{e.inspect}"
- if retried
- puts "Already retried. Raising exception"
- raise e
- else
- puts "Retrying"
- retried = true
- QC::Conn.connection = QC::Conn.connect
- retry
- end
end
def start_workers
+ QC::Conn.disconnect
@pid = fork do
- QC::Conn.connection = QC::Conn.connect
worker = QC::Worker.new(q_name: 'integration_tests')
worker.start
end
diff --git a/activejob/test/support/integration/adapters/resque.rb b/activejob/test/support/integration/adapters/resque.rb
index 03ffd3fd62..9de3e7c879 100644
--- a/activejob/test/support/integration/adapters/resque.rb
+++ b/activejob/test/support/integration/adapters/resque.rb
@@ -17,13 +17,15 @@ module ResqueJobsManager
def start_workers
@resque_thread = Thread.new do
- Resque::Worker.new("integration_tests").work(0.5)
+ w = Resque::Worker.new("integration_tests")
+ w.term_child = true
+ w.work(0.5)
end
@scheduler_thread = Thread.new do
Resque::Scheduler.configure do |c|
c.poll_sleep_amount = 0.5
c.dynamic = true
- c.verbose = true
+ c.quiet = true
c.logfile = nil
end
Resque::Scheduler.master_lock.release!
diff --git a/activejob/test/support/integration/adapters/sidekiq.rb b/activejob/test/support/integration/adapters/sidekiq.rb
index b3c3dcff22..0a0a549c9e 100644
--- a/activejob/test/support/integration/adapters/sidekiq.rb
+++ b/activejob/test/support/integration/adapters/sidekiq.rb
@@ -29,7 +29,6 @@ module SidekiqJobsManager
"--concurrency", "1",
"--timeout", "1",
"--daemon",
- "--verbose"
])
require 'celluloid'
require 'sidekiq/scheduled'
diff --git a/activejob/test/support/integration/adapters/sucker_punch.rb b/activejob/test/support/integration/adapters/sucker_punch.rb
index 691ba35c90..9c0d66b469 100644
--- a/activejob/test/support/integration/adapters/sucker_punch.rb
+++ b/activejob/test/support/integration/adapters/sucker_punch.rb
@@ -1,5 +1,6 @@
module SuckerPunchJobsManager
def setup
ActiveJob::Base.queue_adapter = :sucker_punch
+ SuckerPunch.logger = nil
end
end
diff --git a/activejob/test/support/integration/dummy_app_template.rb b/activejob/test/support/integration/dummy_app_template.rb
index 28aae0f884..65994d6a1c 100644
--- a/activejob/test/support/integration/dummy_app_template.rb
+++ b/activejob/test/support/integration/dummy_app_template.rb
@@ -1,5 +1,5 @@
if ENV['AJADAPTER'] == 'delayed_job'
- generate "delayed_job:active_record"
+ generate "delayed_job:active_record", "--quiet"
rake("db:migrate")
end
diff --git a/activejob/test/support/integration/helper.rb b/activejob/test/support/integration/helper.rb
index ccd5036b36..9bd45e09e8 100644
--- a/activejob/test/support/integration/helper.rb
+++ b/activejob/test/support/integration/helper.rb
@@ -1,6 +1,4 @@
-puts "\n\n"
-puts "*** Running integration tests for #{ENV['AJADAPTER']} ***"
-puts "\n\n"
+puts "*** rake aj:integration:#{ENV['AJADAPTER']} ***\n"
ENV["RAILS_ENV"] = "test"
ActiveJob::Base.queue_name_prefix = nil
@@ -10,7 +8,7 @@ require 'rails/generators/rails/app/app_generator'
dummy_app_path = Dir.mktmpdir + "/dummy"
dummy_app_template = File.expand_path("../dummy_app_template.rb", __FILE__)
args = Rails::Generators::ARGVScrubber.new(["new", dummy_app_path, "--skip-gemfile", "--skip-bundle",
- "--skip-git", "--skip-spring", "-d", "sqlite3", "--skip-javascript", "--force", "--quite",
+ "--skip-git", "--skip-spring", "-d", "sqlite3", "--skip-javascript", "--force", "--quiet",
"--template", dummy_app_template]).prepare!
Rails::Generators::AppGenerator.start args
diff --git a/activemodel/lib/active_model/gem_version.rb b/activemodel/lib/active_model/gem_version.rb
index dd652190f7..e37edcf581 100644
--- a/activemodel/lib/active_model/gem_version.rb
+++ b/activemodel/lib/active_model/gem_version.rb
@@ -8,7 +8,7 @@ module ActiveModel
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index 7ee033ba5f..60439f5631 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -86,6 +86,8 @@ module ActiveModel
validates_with BlockValidator, _merge_attributes(attr_names), &block
end
+ VALID_OPTIONS_FOR_VALIDATE = [:on, :if, :unless].freeze
+
# Adds a validation method or block to the class. This is useful when
# overriding the +validate+ instance method becomes too unwieldy and
# you're looking for more descriptive declaration of your validations.
@@ -144,7 +146,11 @@ module ActiveModel
options = args.extract_options!
if args.all? { |arg| arg.is_a?(Symbol) }
- options.assert_valid_keys([:on, :if, :unless])
+ options.each_key do |k|
+ unless VALID_OPTIONS_FOR_VALIDATE.include?(k)
+ raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{VALID_OPTIONS_FOR_VALIDATE.map(&:inspect).join(', ')}. Perhaps you meant to call `validates` instead of `validate`?")
+ end
+ end
end
if options.key?(:on)
diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb
index d876f73052..de71bb6f42 100644
--- a/activemodel/test/cases/validations_test.rb
+++ b/activemodel/test/cases/validations_test.rb
@@ -167,10 +167,12 @@ class ValidationsTest < ActiveModel::TestCase
end
def test_invalid_options_to_validate
- assert_raises(ArgumentError) do
+ error = assert_raises(ArgumentError) do
# A common mistake -- we meant to call 'validates'
Topic.validate :title, presence: true
end
+ message = 'Unknown key: :presence. Valid keys are: :on, :if, :unless. Perhaps you meant to call `validates` instead of `validate`?'
+ assert_equal message, error.message
end
def test_errors_conversions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index c02de2e979..210151a2ad 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,8 +1,19 @@
+* Honor overridden `rack.test` in Rack environment for the connection
+ management middleware.
+
+ *Simon Eskildsen*
+
+* Add a truncate method to the connection.
+
+ *Aaron Patterson*
+
* Don't autosave unchanged has_one through records.
*Alan Kennedy*, *Steve Parrington*
-* Do not dump foreign keys for ignored tables. *Yves Senn*
+* Do not dump foreign keys for ignored tables.
+
+ *Yves Senn*
* PostgreSQL adapter correctly dumps foreign keys targeting tables
outside the schema search path.
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 18da28d480..12ca3a48a9 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1171,7 +1171,7 @@ module ActiveRecord
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+
# association will use "person_id" as the default <tt>:foreign_key</tt>.
# [:primary_key]
- # Specify the method that returns the primary key used for the association. By default this is +id+.
+ # Specify the name of the column to use as the primary key for the association. By default this is +id+.
# [:dependent]
# Controls what happens to the associated objects when
# their owner is destroyed. Note that these are implemented as
diff --git a/activerecord/lib/active_record/attribute_set/builder.rb b/activerecord/lib/active_record/attribute_set/builder.rb
index 1e146a07da..d4a787f2fe 100644
--- a/activerecord/lib/active_record/attribute_set/builder.rb
+++ b/activerecord/lib/active_record/attribute_set/builder.rb
@@ -23,8 +23,11 @@ module ActiveRecord
end
def add_uninitialized_attributes(attributes)
- types.except(*attributes.keys).each do |name, type|
- attributes[name] = Attribute.uninitialized(name, type)
+ types.each_key do |name|
+ next if attributes.key? name
+ type = types[name]
+ attributes[name] =
+ Attribute.uninitialized(name, type)
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index bc1a670b42..9760729da3 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -640,7 +640,7 @@ module ActiveRecord
end
def call(env)
- testing = env.key?('rack.test')
+ testing = env['rack.test']
response = @app.call(env)
response[2] = ::Rack::BodyProxy.new(response[2]) do
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 98e96099cb..ff8b3e9890 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -83,6 +83,11 @@ module ActiveRecord
exec_query(sql, name, binds)
end
+ # Executes the truncate statement.
+ def truncate(table_name, name = nil)
+ raise NotImplementedError
+ end
+
# Executes update +sql+ statement in the context of this connection using
# +binds+ as the bind substitutes. +name+ is logged along with
# the executed +sql+ statement.
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 037fb69dfb..e4cfe843a8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -389,6 +389,10 @@ module ActiveRecord
end
end
+ def truncate(table_name, name = nil)
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
+ end
+
def table_exists?(name)
return false unless name.present?
return true if tables(nil, nil, name).any?
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 80461f3910..0d74cb6707 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -255,6 +255,10 @@ module ActiveRecord
@statements.clear
end
+ def truncate(table_name, name = nil)
+ exec_query "TRUNCATE TABLE #{quote_table_name(table_name)}", name, []
+ end
+
# Is this connection alive and ready for queries?
def active?
@connection.query 'SELECT 1'
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 1724fa893d..4044f5f7b2 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -661,7 +661,7 @@ module ActiveRecord
row[association.foreign_type] = $1
end
- fk_type = association.active_record.columns_hash[association.foreign_key].type
+ fk_type = association.active_record.columns_hash[fk_name].type
row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
end
when :has_many
diff --git a/activerecord/lib/active_record/gem_version.rb b/activerecord/lib/active_record/gem_version.rb
index 15c9dee712..91747d2ccf 100644
--- a/activerecord/lib/active_record/gem_version.rb
+++ b/activerecord/lib/active_record/gem_version.rb
@@ -8,7 +8,7 @@ module ActiveRecord
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb
index a9ddd9141f..45b6b1c925 100644
--- a/activerecord/lib/active_record/querying.rb
+++ b/activerecord/lib/active_record/querying.rb
@@ -37,7 +37,8 @@ module ActiveRecord
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
def find_by_sql(sql, binds = [])
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds)
- column_types = result_set.column_types.except(*columns_hash.keys)
+ column_types = result_set.column_types.dup
+ columns_hash.each_key { |k| column_types.delete k }
result_set.map { |record| instantiate(record, column_types) }
end
diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb
index 0b2f59b0eb..62c5abbf41 100644
--- a/activerecord/test/cases/adapters/mysql2/connection_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb
@@ -4,6 +4,8 @@ require 'support/connection_helper'
class MysqlConnectionTest < ActiveRecord::TestCase
include ConnectionHelper
+ fixtures :comments
+
def setup
super
@subscriber = SQLSubscriber.new
@@ -24,6 +26,17 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
end
+ def test_truncate
+ rows = ActiveRecord::Base.connection.exec_query("select count(*) from comments")
+ count = rows.first.values.first
+ assert_operator count, :>, 0
+
+ ActiveRecord::Base.connection.truncate("comments")
+ rows = ActiveRecord::Base.connection.exec_query("select count(*) from comments")
+ count = rows.first.values.first
+ assert_equal 0, count
+ end
+
def test_no_automatic_reconnection_after_timeout
assert @connection.active?
@connection.update('set @@wait_timeout=1')
diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb
index d26cda46fa..7d179944d4 100644
--- a/activerecord/test/cases/adapters/postgresql/connection_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb
@@ -8,6 +8,8 @@ module ActiveRecord
class NonExistentTable < ActiveRecord::Base
end
+ fixtures :comments
+
def setup
super
@subscriber = SQLSubscriber.new
@@ -20,6 +22,14 @@ module ActiveRecord
super
end
+ def test_truncate
+ count = ActiveRecord::Base.connection.execute("select count(*) from comments").first['count'].to_i
+ assert_operator count, :>, 0
+ ActiveRecord::Base.connection.truncate("comments")
+ count = ActiveRecord::Base.connection.execute("select count(*) from comments").first['count'].to_i
+ assert_equal 0, count
+ end
+
def test_encoding
assert_not_nil @connection.encoding
end
diff --git a/activerecord/test/cases/connection_management_test.rb b/activerecord/test/cases/connection_management_test.rb
index 77d9ae9b8e..f53c496ecd 100644
--- a/activerecord/test/cases/connection_management_test.rb
+++ b/activerecord/test/cases/connection_management_test.rb
@@ -96,6 +96,14 @@ module ActiveRecord
assert ActiveRecord::Base.connection_handler.active_connections?
end
+ def test_connections_closed_if_exception_and_explicitly_not_test
+ @env['rack.test'] = false
+ app = Class.new(App) { def call(env); raise NotImplementedError; end }.new
+ explosive = ConnectionManagement.new(app)
+ assert_raises(NotImplementedError) { explosive.call(@env) }
+ assert !ActiveRecord::Base.connection_handler.active_connections?
+ end
+
test "doesn't clear active connections when running in a test case" do
@env['rack.test'] = true
@management.call(@env)
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 385ec48005..1050047a43 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -675,7 +675,7 @@ class FoxyFixturesTest < ActiveRecord::TestCase
if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
require 'models/uuid_parent'
require 'models/uuid_child'
- fixtures :uuid_parents, :uuid_children
+ fixtures :uuid_parents, :uuid_children
end
def test_identifies_strings
diff --git a/activerecord/test/models/parrot.rb b/activerecord/test/models/parrot.rb
index e76e83f314..8c83de573f 100644
--- a/activerecord/test/models/parrot.rb
+++ b/activerecord/test/models/parrot.rb
@@ -19,7 +19,7 @@ class LiveParrot < Parrot
end
class DeadParrot < Parrot
- belongs_to :killer, :class_name => 'Pirate'
+ belongs_to :killer, :class_name => 'Pirate', foreign_key: :killer_id
end
class FunkyParrot < Parrot
diff --git a/activesupport/lib/active_support/gem_version.rb b/activesupport/lib/active_support/gem_version.rb
index 0a2b4c1618..6233c45787 100644
--- a/activesupport/lib/active_support/gem_version.rb
+++ b/activesupport/lib/active_support/gem_version.rb
@@ -8,7 +8,7 @@ module ActiveSupport
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index 881faf93f5..f4d504914e 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -98,8 +98,8 @@ class DurationTest < ActiveSupport::TestCase
def test_since_and_ago
t = Time.local(2000)
- assert t + 1, 1.second.since(t)
- assert t - 1, 1.second.ago(t)
+ assert_equal t + 1, 1.second.since(t)
+ assert_equal t - 1, 1.second.ago(t)
end
def test_since_and_ago_without_argument
diff --git a/ci/travis.rb b/ci/travis.rb
index 3ccbd1dad4..a1920a7a1f 100755
--- a/ci/travis.rb
+++ b/ci/travis.rb
@@ -107,6 +107,7 @@ results = {}
ENV['GEM'].split(',').each do |gem|
[false, true].each do |isolated|
+ next if ENV['TRAVIS_PULL_REQUEST'] && ENV['TRAVIS_PULL_REQUEST'] != 'false' && isolated
next if gem == 'railties' && isolated
next if gem == 'aj:integration' && isolated
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md
index 19d61e6f3f..2b8a6eb622 100644
--- a/guides/source/4_2_release_notes.md
+++ b/guides/source/4_2_release_notes.md
@@ -25,9 +25,8 @@ If you're upgrading an existing application, it's a great idea to have good test
coverage before going in. You should also first upgrade to Rails 4.1 in case you
haven't and make sure your application still runs as expected before attempting
to upgrade to Rails 4.2. A list of things to watch out for when upgrading is
-available in the
-[Upgrading Ruby on Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-4-1-to-rails-4-2)
-guide.
+available in the guide: [Upgrading Ruby on
+Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-4-1-to-rails-4-2)
Major Features
@@ -36,9 +35,12 @@ Major Features
### Active Job, Action Mailer #deliver_later
Active Job is a new framework in Rails 4.2. It is an adapter layer on top of
-queuing systems like [Resque](https://github.com/resque/resque), [Delayed Job](https://github.com/collectiveidea/delayed_job), [Sidekiq](https://github.com/mperham/sidekiq), and more. You can write your
-jobs with the Active Job API, and it'll run on all these queues with no changes
-(it comes pre-configured with an inline runner).
+queuing systems like [Resque](https://github.com/resque/resque), [Delayed
+Job](https://github.com/collectiveidea/delayed_job),
+[Sidekiq](https://github.com/mperham/sidekiq), and more.
+
+You can write your jobs with the Active Job API, and it'll run on all these
+queues with no changes (it comes pre-configured with an inline runner).
Building on top of Active Job, Action Mailer now comes with a `#deliver_later`
method, which adds your email to be sent as a job to a queue, so it doesn't
@@ -52,11 +54,16 @@ deserialize it at run time.
### Adequate Record
-Adequate Record is a set of refactorings that make Active Record `find` and `find_by` methods and some association queries upto 2x faster.
+Adequate Record is a set of refactorings that make Active Record `find` and
+`find_by` methods and some association queries upto 2x faster.
-It works by caching SQL query patterns while executing the Active Record calls. The cache helps skip parts of the computation involved in the transformation of the calls into SQL queries. More details in [Aaron Patterson's post](http://tenderlovemaking.com/2014/02/19/adequaterecord-pro-like-activerecord.html).
+It works by caching SQL query patterns while executing the Active Record calls.
+The cache helps skip parts of the computation involved in the transformation of
+the calls into SQL queries. More details in [Aaron Patterson's
+post](http://tenderlovemaking.com/2014/02/19/adequaterecord-pro-like-activerecord.html).
-Nothing special has to be done to activate this feature. Most `find` and `find_by` calls and association queries will use it automatically. Examples:
+Nothing special has to be done to activate this feature. Most `find` and
+`find_by` calls and association queries will use it automatically. Examples:
```ruby
Post.find 1 # caches query pattern
@@ -142,6 +149,13 @@ individual components for new deprecations in this release.
The following changes may require immediate action upon upgrade.
+### `render` with a String argument
+
+Previously, calling `render "foo/bar"` in a controller action is equivalent to
+`render file: "foo/bar"`. In Rails 4.2, this has been changed to mean `render template: "foo/bar"`
+instead. If you need to render a file, please change your code to use the
+explicit form (`render file: "foo/bar"`) instead.
+
### `respond_with` / class-level `respond_to`
`respond_with` and the corresponding class-level `respond_to` have been moved to
@@ -492,6 +506,10 @@ Please refer to the [Changelog][action-view] for detailed changes.
### Notable changes
+* `render "foo/bar"` now expands to `render template: "foo/bar"` instead of
+ `render file: "foo/bar"`.
+ ([Pull Request](https://github.com/rails/rails/pull/16888))
+
* Introduced a `#{partial_name}_iteration` special local variable for use with
partials that are rendered with a collection. It provides access to the
current state of the iteration via the `#index`, `#size`, `#first?` and
@@ -690,7 +708,7 @@ Please refer to the [Changelog][active-model] for detailed changes.
(Pull Request [1](https://github.com/rails/rails/pull/14861),
[2](https://github.com/rails/rails/pull/16180))
-* `has_secure_password` no longer disallow blank passwords (i.e. passwords
+* `has_secure_password` no longer disallows blank passwords (i.e. passwords
that contains only spaces) by default.
([Pull Request](https://github.com/rails/rails/pull/16412))
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index f2831defe6..9c34418fab 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -99,41 +99,13 @@ If no adapter is set, the job is immediately executed.
### Backends
-Active Job has adapters for the following queueing backends:
-
-* [Backburner](https://github.com/nesquena/backburner)
-* [Delayed Job](https://github.com/collectiveidea/delayed_job)
-* [Qu](https://github.com/bkeepers/qu)
-* [Que](https://github.com/chanks/que)
-* [QueueClassic 2.x](https://github.com/ryandotsmith/queue_classic/tree/v2.2.3)
-* [Resque 1.x](https://github.com/resque/resque/tree/1-x-stable)
-* [Sidekiq](https://github.com/mperham/sidekiq)
-* [Sneakers](https://github.com/jondot/sneakers)
-* [Sucker Punch](https://github.com/brandonhilkert/sucker_punch)
-
-#### Backends Features
-
-| | Async | Queues | Delayed | Priorities | Timeout | Retries |
-|-----------------------|-------|--------|-----------|------------|---------|---------|
-| **Backburner** | Yes | Yes | Yes | Yes | Job | Global |
-| **Delayed Job** | Yes | Yes | Yes | Job | Global | Global |
-| **Que** | Yes | Yes | Yes | Job | No | Job |
-| **Queue Classic** | Yes | Yes | No* | No | No | No |
-| **Resque** | Yes | Yes | Yes (Gem) | Queue | Global | Yes |
-| **Sidekiq** | Yes | Yes | Yes | Queue | No | Job |
-| **Sneakers** | Yes | Yes | No | Queue | Queue | No |
-| **Sucker Punch** | Yes | Yes | No | No | No | No |
-| **Active Job Inline** | No | Yes | N/A | N/A | N/A | N/A |
-| **Active Job** | Yes | Yes | Yes | No | No | No |
-
-NOTE:
-* Queue Classic does not support Job scheduling. However you can implement this
-yourself or you can use the queue_classic-later gem. See the documentation for
-ActiveJob::QueueAdapters::QueueClassicAdapter.
-
-### Change Backends
-
-You can easily change your adapter:
+Active Job has built-in adapters for multiple queueing backends (Sidekiq,
+Resque, Delayed Job and others). To get an up-to-date list of the adapters
+see the API Documentation for [ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
+
+### Changing the Backend
+
+You can easily change your queueing backend:
```ruby
# be sure to have the adapter gem in your Gemfile and follow the adapter specific
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 220946e8d5..7b9710bcd8 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -62,7 +62,7 @@ These configuration methods are to be called on a `Rails::Railtie` object, such
* `config.autoload_paths` accepts an array of paths from which Rails will autoload constants. Default is all directories under `app`.
-* `config.cache_classes` controls whether or not application classes and modules should be reloaded on each request. Defaults to false in development mode, and true in test and production modes. Can also be enabled with `threadsafe!`.
+* `config.cache_classes` controls whether or not application classes and modules should be reloaded on each request. Defaults to false in development mode, and true in test and production modes.
* `config.action_view.cache_template_loading` controls whether or not templates should be reloaded on each request. Defaults to whatever is set for `config.cache_classes`.
@@ -86,7 +86,7 @@ application. Accepts a valid week day symbol (e.g. `:monday`).
end
```
-* `config.dependency_loading` is a flag that allows you to disable constant autoloading setting it to false. It only has effect if `config.cache_classes` is true, which it is by default in production mode. This flag is set to false by `config.threadsafe!`.
+* `config.dependency_loading` is a flag that allows you to disable constant autoloading setting it to false. It only has effect if `config.cache_classes` is true, which it is by default in production mode.
* `config.eager_load` when true, eager loads all registered `config.eager_load_namespaces`. This includes your application, engines, Rails frameworks and any other registered namespace.
@@ -364,6 +364,29 @@ encrypted cookies salt value. Defaults to `'signed encrypted cookie'`.
method should be performed on the parameters. See [Security Guide](security.html#unsafe-query-generation)
for more information. It defaults to true.
+* `config.action_dispatch.rescue_responses` configures what exceptions are assigned to an HTTP status. It accepts a hash and you can specify pairs of exception/status. By default, this is defined as:
+
+ ```ruby
+ config.action_dispatch.rescue_responses = {
+ 'ActionController::RoutingError' => :not_found,
+ 'AbstractController::ActionNotFound' => :not_found,
+ 'ActionController::MethodNotAllowed' => :method_not_allowed,
+ 'ActionController::UnknownHttpMethod' => :method_not_allowed,
+ 'ActionController::NotImplemented' => :not_implemented,
+ 'ActionController::UnknownFormat' => :not_acceptable,
+ 'ActionController::InvalidAuthenticityToken' => :unprocessable_entity,
+ 'ActionDispatch::ParamsParser::ParseError' => :bad_request,
+ 'ActionController::BadRequest' => :bad_request,
+ 'ActionController::ParameterMissing' => :bad_request,
+ 'ActiveRecord::RecordNotFound' => :not_found,
+ 'ActiveRecord::StaleObjectError' => :conflict,
+ 'ActiveRecord::RecordInvalid' => :unprocessable_entity,
+ 'ActiveRecord::RecordNotSaved' => :unprocessable_entity
+ }
+ ```
+
+ Any execptions that are not configured will be assigned to 500 Internal server error.
+
* `ActionDispatch::Callbacks.before` takes a block of code to run before the request.
* `ActionDispatch::Callbacks.to_prepare` takes a block to run after `ActionDispatch::Callbacks.before`, but before the request. Runs for every request in `development` mode, but only once for `production` or environments with `cache_classes` set to `true`.
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index 8bc4b10591..302c4ca9c0 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -559,6 +559,23 @@ $ git push origin my_pull_request -f
You should be able to refresh the pull request on GitHub and see that it has
been updated.
+#### Updating pull request
+
+Sometimes you will be asked to make some changes to the code you have
+already committed. This can include amending existing commits. In this
+case Git will not allow you to push the changes as the pushed branch
+and local branch do not match. Instead of opening a new pull request,
+you can force push to your branch on GitHub as described earlier in
+squashing commits section:
+
+```bash
+$ git push origin my_pull_request -f
+```
+
+This will update the branch and pull request on GitHub with your new code. Do
+note that using force push may result in commits being lost on the remote branch; use it with care.
+
+
### Older Versions of Ruby on Rails
If you want to add a fix to older versions of Ruby on Rails, you'll need to set up and switch to your own local tracking branch. Here is an example to switch to the 4-0-stable branch:
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 4e538693f7..7267ef1b4f 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -111,7 +111,7 @@ Record callbacks.
When you define a `after_rollback` or `after_commit` callback, you
will receive a deprecation warning about this upcoming change. When
-you are ready, you can opt into the new behvaior and remove the
+you are ready, you can opt into the new behavior and remove the
deprecation warning by adding following configuration to your
`config/application.rb`:
@@ -186,15 +186,6 @@ venerable html-scanner approach is now officially being deprecated in favor of
This means the methods `sanitize`, `sanitize_css`, `strip_tags` and
`strip_links` are backed by a new implementation.
-In the next major Rails version `Rails Html Sanitizer` will be the default
-sanitizer. It already is for new applications.
-
-Include this in your Gemfile to try it out today:
-
-```ruby
-gem 'rails-html-sanitizer'
-```
-
This new sanitizer uses [Loofah](https://github.com/flavorjones/loofah) internally. Loofah in turn uses Nokogiri, which
wraps XML parsers written in both C and Java, so sanitization should be faster
no matter which Ruby version you run.
@@ -209,6 +200,12 @@ Read the [gem's readme](https://github.com/rails/rails-html-sanitizer) for more
The documentation for `PermitScrubber` and `TargetScrubber` explains how you
can gain complete control over when and how elements should be stripped.
+If your application needs to old behaviour include `rails-deprecated_sanitizer` in your Gemfile:
+
+```ruby
+gem 'rails-deprecated_sanitizer'
+```
+
### Rails DOM Testing
TODO: Mention https://github.com/rails/rails/commit/4e97d7585a2f4788b9eed98c6cdaf4bb6f2cf5ce
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 2e7f134101..1e1afef26d 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Remove --skip-action-view option from Rails::Generators::AppBase
+
+ Fixes #17023.
+
+ *Dan Olson*
+
* Specify dummy app's db migrate path in plugin's test_helper.rb.
Fixes #16877.
diff --git a/railties/lib/rails/gem_version.rb b/railties/lib/rails/gem_version.rb
index 672b78c599..4411ec33ef 100644
--- a/railties/lib/rails/gem_version.rb
+++ b/railties/lib/rails/gem_version.rb
@@ -8,7 +8,7 @@ module Rails
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 1cdad09391..0d95bb48e0 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -44,9 +44,6 @@ module Rails
class_option :skip_gems, type: :array, default: [],
desc: 'Skip the provided gems files'
- class_option :skip_action_view, type: :boolean, aliases: '-V', default: false,
- desc: 'Skip Action View files'
-
class_option :skip_sprockets, type: :boolean, aliases: '-S', default: false,
desc: 'Skip Sprockets files'
@@ -167,7 +164,7 @@ module Rails
end
def include_all_railties?
- !options[:skip_active_record] && !options[:skip_action_view] && !options[:skip_test_unit] && !options[:skip_sprockets]
+ !options[:skip_active_record] && !options[:skip_test_unit] && !options[:skip_sprockets]
end
def comment_if(value)
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 7b1a6aa854..2567469c95 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -15,9 +15,6 @@ source 'https://rubygems.org'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
-# Use Rails Html Sanitizer for HTML sanitization
-gem 'rails-html-sanitizer', '~> 1.0'
-
# Use Unicorn as the app server
# gem 'unicorn'
@@ -34,7 +31,7 @@ group :development, :test do
<%- end -%>
# Access an IRB console on exception pages or by using <%%= console %> in views
- gem 'web-console', github: 'rails/web-console', branch: 'master'
+ gem 'web-console', '~> 2.0.0.beta4'
<%- if spring_install? %>
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index 9445c2454e..111b680e4b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -9,7 +9,7 @@ require "active_job/railtie"
<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
-<%= comment_if :skip_action_view %>require "action_view/railtie"
+require "action_view/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test_unit %>require "rails/test_unit/railtie"
<% end -%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb
index 5508829f6b..b2aa82344a 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb
@@ -7,7 +7,7 @@ require 'rails/all'
<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
-<%= comment_if :skip_action_view %>require "action_view/railtie"
+require "action_view/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test_unit %>require "rails/test_unit/railtie"
<% end -%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
index c6e2247e16..28cdfecf81 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
@@ -13,6 +13,6 @@ Rails.backtrace_cleaner.remove_silencers!
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
# Load fixtures from the engine
-if ActiveSupport::TestCase.method_defined?(:fixture_path=)
+if ActiveSupport::TestCase.respond_to?(:fixture_path=)
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
end
diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb
index 9502876ebb..357aebf584 100644
--- a/railties/lib/rails/info.rb
+++ b/railties/lib/rails/info.rb
@@ -22,17 +22,6 @@ module Rails
rescue Exception
end
- def frameworks
- %w( active_record action_pack action_view action_mailer active_support active_model )
- end
-
- def framework_version(framework)
- if Object.const_defined?(framework.classify)
- require "#{framework}/version"
- framework.classify.constantize.version.to_s
- end
- end
-
def to_s
column_width = properties.names.map {|name| name.length}.max
info = properties.map do |name, value|
@@ -61,6 +50,11 @@ module Rails
end
end
+ # The Rails version.
+ property 'Rails version' do
+ Rails.version.to_s
+ end
+
# The Ruby version and platform, e.g. "2.0.0-p247 (x86_64-darwin12.4.0)".
property 'Ruby version' do
"#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_PLATFORM})"
@@ -75,23 +69,10 @@ module Rails
::Rack.release
end
- # The Rails version.
- property 'Rails version' do
- Rails.version.to_s
- end
-
property 'JavaScript Runtime' do
ExecJS.runtime.name
end
- # Versions of each Rails framework (Active Record, Action Pack,
- # Action Mailer, and Active Support).
- frameworks.each do |framework|
- property "#{framework.titlecase} version" do
- framework_version(framework)
- end
- end
-
property 'Middleware' do
Rails.configuration.middleware.map(&:inspect)
end
diff --git a/railties/lib/rails/templates/rails/welcome/index.html.erb b/railties/lib/rails/templates/rails/welcome/index.html.erb
index eb620caa00..89792066d5 100644
--- a/railties/lib/rails/templates/rails/welcome/index.html.erb
+++ b/railties/lib/rails/templates/rails/welcome/index.html.erb
@@ -19,13 +19,13 @@
}
a {color: #03c}
+
a:hover {
background-color: #03c;
color: white;
text-decoration: none;
}
-
#page {
background-color: #f0f0f0;
width: 750px;
@@ -57,21 +57,21 @@
padding-right: 30px;
}
-
#header {
background-image: url(data:image/png;base64,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);
background-repeat: no-repeat;
background-position: top left;
height: 64px;
}
+
#header h1, #header h2 {margin: 0}
+
#header h2 {
color: #888;
font-weight: normal;
font-size: 16px;
}
-
#about h3 {
margin: 0;
margin-bottom: 10px;
@@ -84,18 +84,26 @@
margin-left: -55px;
margin-right: -10px;
}
+
#about-content table {
margin-top: 10px;
margin-bottom: 10px;
font-size: 11px;
border-collapse: collapse;
}
+
#about-content td {
padding: 10px;
padding-top: 3px;
padding-bottom: 3px;
}
- #about-content td.name {color: #555}
+
+ #about-content td.name {
+ font-weight: bold;
+ vertical-align: top;
+ color: #555;
+ }
+
#about-content td.value {color: #000}
#about-content ul {
@@ -107,21 +115,23 @@
background-color: #fcc;
border: 1px solid #f00;
}
+
#about-content.failure p {
margin: 0;
padding: 10px;
}
-
#getting-started {
border-top: 1px solid #ccc;
margin-top: 25px;
padding-top: 15px;
}
+
#getting-started h1 {
margin: 0;
font-size: 20px;
}
+
#getting-started h2 {
margin: 0;
font-size: 14px;
@@ -129,40 +139,46 @@
color: #333;
margin-bottom: 25px;
}
+
#getting-started ol {
margin-left: 0;
padding-left: 0;
}
+
#getting-started li {
font-size: 18px;
color: #888;
margin-bottom: 25px;
}
+
#getting-started li h2 {
margin: 0;
font-weight: normal;
font-size: 18px;
color: #333;
}
+
#getting-started li p {
color: #555;
font-size: 13px;
}
-
#sidebar ul {
margin-left: 0;
padding-left: 0;
}
+
#sidebar ul h3 {
margin-top: 25px;
font-size: 16px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
}
+
#sidebar li {
list-style-type: none;
}
+
#sidebar ul.links li {
margin-bottom: 5px;
}
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index f8b4ee30d8..0eddf644d9 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -182,7 +182,7 @@ module ApplicationTests
test "application is always added to eager_load namespaces" do
require "#{app_path}/config/application"
- assert Rails.application, Rails.application.config.eager_load_namespaces
+ assert_includes Rails.application.config.eager_load_namespaces, AppTemplate::Application
end
test "the application can be eager loaded even when there are no frameworks" do
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index d687a8f506..b492258efb 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -268,11 +268,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
- def test_generator_if_skip_action_view_is_given
- run_generator [destination_root, "--skip-action-view"]
- assert_file "config/application.rb", /#\s+require\s+["']action_view\/railtie["']/
- end
-
def test_generator_if_skip_sprockets_is_given
run_generator [destination_root, "--skip-sprockets"]
assert_no_file "config/initializers/assets.rb"
diff --git a/railties/test/rails_info_test.rb b/railties/test/rails_info_test.rb
index 4bec302ff8..92e4af25b5 100644
--- a/railties/test/rails_info_test.rb
+++ b/railties/test/rails_info_test.rb
@@ -38,21 +38,10 @@ class InfoTest < ActiveSupport::TestCase
end
def test_rails_version
- assert_property 'Rails version',
+ assert_property 'Rails version',
File.read(File.realpath('../../../RAILS_VERSION', __FILE__)).chomp
end
- def test_framework_version
- assert_property 'Active Support version', ActiveSupport.version.to_s
- end
-
- def test_frameworks_exist
- Rails::Info.frameworks.each do |framework|
- dir = File.dirname(__FILE__) + "/../../" + framework.delete('_')
- assert File.directory?(dir), "#{framework.classify} does not exist"
- end
- end
-
def test_html_includes_middleware
Rails::Info.module_eval do
property 'Middleware', ['Rack::Lock', 'Rack::Static']
diff --git a/version.rb b/version.rb
index 672b78c599..4411ec33ef 100644
--- a/version.rb
+++ b/version.rb
@@ -8,7 +8,7 @@ module Rails
MAJOR = 4
MINOR = 2
TINY = 0
- PRE = "beta1"
+ PRE = "beta2"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end