diff options
-rw-r--r-- | activejob/CHANGELOG.md | 4 | ||||
-rw-r--r-- | activejob/lib/active_job/exceptions.rb | 6 | ||||
-rw-r--r-- | activejob/test/cases/exceptions_test.rb | 4 | ||||
-rw-r--r-- | activejob/test/jobs/retry_job.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/base.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/no_touching.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/sanitization.rb | 9 | ||||
-rw-r--r-- | activerecord/test/cases/finder_test.rb | 5 | ||||
-rw-r--r-- | activerecord/test/cases/touch_later_test.rb | 9 | ||||
-rw-r--r-- | activesupport/test/caching_test.rb | 5 | ||||
-rw-r--r-- | guides/source/i18n.md | 2 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.md | 2 |
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 |