aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activejob/CHANGELOG.md4
-rw-r--r--activejob/lib/active_job/exceptions.rb6
-rw-r--r--activejob/test/cases/exceptions_test.rb4
-rw-r--r--activejob/test/jobs/retry_job.rb2
-rw-r--r--activerecord/lib/active_record/base.rb2
-rw-r--r--activerecord/lib/active_record/no_touching.rb4
-rw-r--r--activerecord/lib/active_record/sanitization.rb9
-rw-r--r--activerecord/test/cases/finder_test.rb5
-rw-r--r--activerecord/test/cases/touch_later_test.rb9
-rw-r--r--activesupport/test/caching_test.rb5
-rw-r--r--guides/source/i18n.md2
-rw-r--r--guides/source/upgrading_ruby_on_rails.md2
12 files changed, 28 insertions, 26 deletions
diff --git a/activejob/CHANGELOG.md b/activejob/CHANGELOG.md
index 12f9e1cc17..585ade7229 100644
--- a/activejob/CHANGELOG.md
+++ b/activejob/CHANGELOG.md
@@ -1,5 +1,9 @@
## Rails 5.1.0.alpha ##
+* Yield the job instance so you have access to things like `job.arguments` on the custom logic after retries fail.
+
+ *DHH*
+
* Added declarative exception handling via `ActiveJob::Base.retry_on` and `ActiveJob::Base.discard_on`.
Examples:
diff --git a/activejob/lib/active_job/exceptions.rb b/activejob/lib/active_job/exceptions.rb
index a8ff55fbe4..f8d76587ad 100644
--- a/activejob/lib/active_job/exceptions.rb
+++ b/activejob/lib/active_job/exceptions.rb
@@ -12,7 +12,7 @@ module ActiveJob
# holding queue for inspection.
#
# You can also pass a block that'll be invoked if the retry attempts fail for custom logic rather than letting
- # the exception bubble up.
+ # the exception bubble up. This block is yielded with the job instance as the first and the error instance as the second parameter.
#
# ==== Options
# * <tt>:wait</tt> - Re-enqueues the job with a delay specified either in seconds (default: 3 seconds),
@@ -28,7 +28,7 @@ module ActiveJob
# class RemoteServiceJob < ActiveJob::Base
# retry_on CustomAppException # defaults to 3s wait, 5 attempts
# retry_on AnotherCustomAppException, wait: ->(executions) { executions * 2 }
- # retry_on(YetAnotherCustomAppException) do |exception|
+ # retry_on(YetAnotherCustomAppException) do |job, exception|
# ExceptionNotifier.caught(exception)
# end
# retry_on ActiveRecord::StatementInvalid, wait: 5.seconds, attempts: 3
@@ -47,7 +47,7 @@ module ActiveJob
retry_job wait: determine_delay(wait), queue: queue, priority: priority
else
if block_given?
- yield exception
+ yield self, exception
else
logger.error "Stopped retrying #{self.class} due to a #{exception}, which reoccurred on #{executions} attempts. The original exception was #{error.cause.inspect}."
raise error
diff --git a/activejob/test/cases/exceptions_test.rb b/activejob/test/cases/exceptions_test.rb
index 30e43c99cb..9ee1dbfa0a 100644
--- a/activejob/test/cases/exceptions_test.rb
+++ b/activejob/test/cases/exceptions_test.rb
@@ -58,8 +58,8 @@ class ExceptionsTest < ActiveJob::TestCase
test "custom handling of job that exceeds retry attempts" do
perform_enqueued_jobs do
- RetryJob.perform_later "CustomCatchError", 6
- assert_equal "Dealt with a job that failed to retry in a custom way", JobBuffer.last_value
+ RetryJob.perform_later 'CustomCatchError', 6
+ assert_equal "Dealt with a job that failed to retry in a custom way after 6 attempts", JobBuffer.last_value
end
end
diff --git a/activejob/test/jobs/retry_job.rb b/activejob/test/jobs/retry_job.rb
index be20156984..c02febc50c 100644
--- a/activejob/test/jobs/retry_job.rb
+++ b/activejob/test/jobs/retry_job.rb
@@ -15,7 +15,7 @@ class RetryJob < ActiveJob::Base
retry_on ShortWaitTenAttemptsError, wait: 1.second, attempts: 10
retry_on ExponentialWaitTenAttemptsError, wait: :exponentially_longer, attempts: 10
retry_on CustomWaitTenAttemptsError, wait: ->(executions) { executions * 2 }, attempts: 10
- retry_on(CustomCatchError) { |exception| JobBuffer.add("Dealt with a job that failed to retry in a custom way") }
+ retry_on(CustomCatchError) { |job, exception| JobBuffer.add("Dealt with a job that failed to retry in a custom way after #{job.arguments.second} attempts") }
discard_on DiscardableError
def perform(raising, attempts)
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 01d7886406..1e7e939097 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -312,8 +312,8 @@ module ActiveRecord #:nodoc:
include NestedAttributes
include Aggregations
include Transactions
- include NoTouching
include TouchLater
+ include NoTouching
include Reflection
include Serialization
include Store
diff --git a/activerecord/lib/active_record/no_touching.rb b/activerecord/lib/active_record/no_touching.rb
index edb5066fa0..4059020e25 100644
--- a/activerecord/lib/active_record/no_touching.rb
+++ b/activerecord/lib/active_record/no_touching.rb
@@ -45,6 +45,10 @@ module ActiveRecord
NoTouching.applied_to?(self.class)
end
+ def touch_later(*) # :nodoc:
+ super unless no_touching?
+ end
+
def touch(*) # :nodoc:
super unless no_touching?
end
diff --git a/activerecord/lib/active_record/sanitization.rb b/activerecord/lib/active_record/sanitization.rb
index 6617008344..c40e98715e 100644
--- a/activerecord/lib/active_record/sanitization.rb
+++ b/activerecord/lib/active_record/sanitization.rb
@@ -5,13 +5,6 @@ module ActiveRecord
extend ActiveSupport::Concern
module ClassMethods
- # Used to sanitize objects before they're used in an SQL SELECT statement.
- # Delegates to {connection.quote}[rdoc-ref:ConnectionAdapters::Quoting#quote].
- def sanitize(object) # :nodoc:
- connection.quote(object)
- end
- alias_method :quote_value, :sanitize
-
protected
# Accepts an array or string of SQL conditions and sanitizes
@@ -216,7 +209,7 @@ module ActiveRecord
# TODO: Deprecate this
def quoted_id # :nodoc:
- self.class.quote_value(@attributes[self.class.primary_key].value_for_database)
+ self.class.connection.quote(@attributes[self.class.primary_key].value_for_database)
end
end
end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 85b6b0da0e..31bc4fa1f2 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -874,11 +874,6 @@ class FinderTest < ActiveRecord::TestCase
assert_kind_of Time, Topic.where(["id = :id", { id: 1 }]).first.written_on
end
- def test_string_sanitation
- assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
- assert_equal "'something; select table'", ActiveRecord::Base.sanitize("something; select table")
- end
-
def test_count_by_sql
assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3"))
assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
diff --git a/activerecord/test/cases/touch_later_test.rb b/activerecord/test/cases/touch_later_test.rb
index 697447a4f3..d1e8c649d9 100644
--- a/activerecord/test/cases/touch_later_test.rb
+++ b/activerecord/test/cases/touch_later_test.rb
@@ -24,6 +24,15 @@ class TouchLaterTest < ActiveRecord::TestCase
assert_not invoice.changed?
end
+ def test_touch_later_respects_no_touching_policy
+ time = Time.now.utc - 25.days
+ topic = Topic.create!(updated_at: time, created_at: time)
+ Topic.no_touching do
+ topic.touch_later
+ end
+ assert_equal time.to_i, topic.updated_at.to_i
+ end
+
def test_touch_later_update_the_attributes
time = Time.now.utc - 25.days
topic = Topic.create!(updated_at: time, created_at: time)
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index 4e47465726..a669d666be 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -831,11 +831,6 @@ class FileStoreTest < ActiveSupport::TestCase
@cache.clear
end
- def test_long_keys
- @cache.write("a"*10000, 1)
- assert_equal 1, @cache.read("a"*10000)
- end
-
def test_long_uri_encoded_keys
@cache.write("%"*870, 1)
assert_equal 1, @cache.read("%"*870)
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 850f0def03..e623f8cf8a 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -866,7 +866,7 @@ This way you can provide special translations for various error messages at diff
#### Error Message Interpolation
-The translated model name, translated attribute name, and value are always available for interpolation.
+The translated model name, translated attribute name, and value are always available for interpolation as `model`, `attribute` and `value` respectively.
So, for example, instead of the default error message `"cannot be blank"` you could use the attribute name like this : `"Please fill in your %{attribute}"`.
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 8fcbf3ed4b..a8afa0ca6e 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -94,6 +94,8 @@ class ApplicationRecord < ActiveRecord::Base
end
```
+Then make sure that all your models inherit from it.
+
### Halting Callback Chains via `throw(:abort)`
In Rails 4.2, when a 'before' callback returns `false` in Active Record