Add implicit receiver support to `Object#with_options`

This commit is contained in:
Pavel Pravosud 2014-07-29 13:50:56 -04:00
parent d035124a20
commit 0cb3cc4ff7
3 changed files with 29 additions and 2 deletions

View File

@ -1,3 +1,8 @@
* `Object#with_options` executes block in merging option context when
explicit receiver in not passed.
*Pavel Pravosud*
* Fixed a compatibility issue with the `Oj` gem when cherry-picking the file
`active_support/core_ext/object/json` without requiring `active_support/json`.

View File

@ -34,9 +34,22 @@ class Object
# body i18n.t :body, user_name: user.name
# end
#
# When you don't pass an explicit receiver, it executes the whole block
# in merging options context:
#
# class Account < ActiveRecord::Base
# with_options dependent: :destroy do
# has_many :customers
# has_many :products
# has_many :invoices
# has_many :expenses
# end
# end
#
# <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
# Each nesting level will merge inherited defaults in addition to their own.
def with_options(options)
yield ActiveSupport::OptionMerger.new(self, options)
def with_options(options, &block)
option_merger = ActiveSupport::OptionMerger.new(self, options)
block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
end
end

View File

@ -79,6 +79,15 @@ class OptionMergerTest < ActiveSupport::TestCase
assert_equal ActiveSupport::OptionMerger, ActiveSupport::OptionMerger.new('', '').class
end
def test_option_merger_implicit_receiver
@options.with_options foo: "bar" do
merge! fizz: "buzz"
end
expected = { hello: "world", foo: "bar", fizz: "buzz" }
assert_equal expected, @options
end
private
def method_with_options(options = {})
options