diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index b32c97bead..5894dab230 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,6 +1,6 @@ * Added yield to Object#presence, so you can do this: - project.account.owner.presence { |p| p.name.first } || 'Nobody' + project.account.owner.presence { name.first } || 'Nobody' instead of calling twice (which may incur double SQL calls): diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb index 893858fcd6..99fd22ff56 100644 --- a/activesupport/lib/active_support/core_ext/object/blank.rb +++ b/activesupport/lib/active_support/core_ext/object/blank.rb @@ -40,15 +40,16 @@ class Object # region = params[:state].presence || params[:country].presence || 'US' # # You can also use this with a block that will be yielded if the object is present - # and the result of that block will then be returned + # and the result of that block will then be returned. The block itself is run against + # the instance you're running #presence on (using instance_eval) # - # project.account.owner.presence { |p| p.name.first } || 'Nobody' + # project.account.owner.presence { name.first } || 'Nobody' # # @return [Object] - def presence + def presence(&block) if present? if block_given? - yield self + instance_eval(&block) else self end diff --git a/activesupport/test/core_ext/object/blank_test.rb b/activesupport/test/core_ext/object/blank_test.rb index 7b3f10b4da..34d10c6981 100644 --- a/activesupport/test/core_ext/object/blank_test.rb +++ b/activesupport/test/core_ext/object/blank_test.rb @@ -35,7 +35,7 @@ class BlankTest < ActiveSupport::TestCase end def test_presence_with_a_block - assert_equal "SALLY", "sally".presence(&:upcase) || "Nobody" - assert_equal "Nobody", nil.presence(&:upcase) || "Nobody" + assert_equal "SALLY", "sally".presence { upcase } || "Nobody" + assert_equal "Nobody", nil.presence { upcase } || "Nobody" end end