diff options
-rw-r--r-- | activesupport/CHANGELOG.md | 7 | ||||
-rw-r--r-- | activesupport/lib/active_support/current_attributes.rb | 6 | ||||
-rw-r--r-- | activesupport/test/current_attributes_test.rb | 37 |
3 files changed, 41 insertions, 9 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 1e726ceb54..2da774ca66 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,4 +1,8 @@ -* Remove the `` Kernel#` `` override that suppresses ENOENT and accidentally returns nil on Unix systems +* Add `before_reset` callback to `CurrentAttributes` and define `after_reset` as an alias of `resets` for symmetry. + + *Rosa Gutierrez* + +* Remove the `` Kernel#` `` override that suppresses ENOENT and accidentally returns nil on Unix systems. *Akinori Musha* @@ -8,7 +12,6 @@ *Stefan Schüßler* - ## Rails 6.0.0.beta1 (January 18, 2019) ## * Remove deprecated `Module#reachable?` method. diff --git a/activesupport/lib/active_support/current_attributes.rb b/activesupport/lib/active_support/current_attributes.rb index 3145ff87a1..67ebe102d7 100644 --- a/activesupport/lib/active_support/current_attributes.rb +++ b/activesupport/lib/active_support/current_attributes.rb @@ -119,10 +119,16 @@ module ActiveSupport end end + # Calls this block before #reset is called on the instance. Used for resetting external collaborators that depend on current values. + def before_reset(&block) + set_callback :reset, :before, &block + end + # Calls this block after #reset is called on the instance. Used for resetting external collaborators, like Time.zone. def resets(&block) set_callback :reset, :after, &block end + alias_method :after_reset, :resets delegate :set, :reset, to: :instance diff --git a/activesupport/test/current_attributes_test.rb b/activesupport/test/current_attributes_test.rb index 1669f08f68..adbdc646bc 100644 --- a/activesupport/test/current_attributes_test.rb +++ b/activesupport/test/current_attributes_test.rb @@ -3,13 +3,18 @@ require "abstract_unit" class CurrentAttributesTest < ActiveSupport::TestCase - Person = Struct.new(:name, :time_zone) + Person = Struct.new(:id, :name, :time_zone) class Current < ActiveSupport::CurrentAttributes attribute :world, :account, :person, :request delegate :time_zone, to: :person - resets { Time.zone = "UTC" } + before_reset { Session.previous = person.try(:id) } + + resets do + Time.zone = "UTC" + Session.current = nil + end def account=(account) super @@ -19,6 +24,7 @@ class CurrentAttributesTest < ActiveSupport::TestCase def person=(person) super Time.zone = person.try(:time_zone) + Session.current = person.try(:id) end def request @@ -30,9 +36,14 @@ class CurrentAttributesTest < ActiveSupport::TestCase end end + class Session < ActiveSupport::CurrentAttributes + attribute :current, :previous + end + setup do @original_time_zone = Time.zone Current.reset + Session.reset end teardown do @@ -56,16 +67,28 @@ class CurrentAttributesTest < ActiveSupport::TestCase end test "set auxiliary class via overwritten method" do - Current.person = Person.new("David", "Central Time (US & Canada)") + Current.person = Person.new(42, "David", "Central Time (US & Canada)") assert_equal "Central Time (US & Canada)", Time.zone.name + assert_equal 42, Session.current end - test "resets auxiliary class via callback" do - Current.person = Person.new("David", "Central Time (US & Canada)") + test "resets auxiliary classes via callback" do + Current.person = Person.new(42, "David", "Central Time (US & Canada)") assert_equal "Central Time (US & Canada)", Time.zone.name Current.reset assert_equal "UTC", Time.zone.name + assert_nil Session.current + end + + test "set auxiliary class based on current attributes via before callback" do + Current.person = Person.new(42, "David", "Central Time (US & Canada)") + assert_nil Session.previous + assert_equal 42, Session.current + + Current.reset + assert_equal 42, Session.previous + assert_nil Session.current end test "set attribute only via scope" do @@ -92,13 +115,13 @@ class CurrentAttributesTest < ActiveSupport::TestCase end test "delegation" do - Current.person = Person.new("David", "Central Time (US & Canada)") + Current.person = Person.new(42, "David", "Central Time (US & Canada)") assert_equal "Central Time (US & Canada)", Current.time_zone assert_equal "Central Time (US & Canada)", Current.instance.time_zone end test "all methods forward to the instance" do - Current.person = Person.new("David", "Central Time (US & Canada)") + Current.person = Person.new(42, "David", "Central Time (US & Canada)") assert_equal "David, in Central Time (US & Canada)", Current.intro assert_equal "David, in Central Time (US & Canada)", Current.instance.intro end |