1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #33437 from CodingAnarchy/delegate_missing_allow_nil

Add :allow_nil option to delegate_missing_to
This commit is contained in:
George Claghorn 2019-05-23 12:33:34 -04:00 committed by GitHub
commit 639d7beb0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 5 deletions

View file

@ -1,3 +1,18 @@
* Method calls on singular attachments return `nil` when no file is attached.
Previously, assuming the following User model, `user.avatar.filename` would
raise a `Module::DelegationError` if no avatar was attached:
```ruby
class User < ApplicationRecord
has_one_attached :avatar
end
```
They now return `nil`.
*Matthew Tanous*
* The mirror service supports direct uploads. * The mirror service supports direct uploads.
New files are directly uploaded to the primary service. When a New files are directly uploaded to the primary service. When a

View file

@ -3,7 +3,7 @@
module ActiveStorage module ActiveStorage
# Representation of a single attachment to a model. # Representation of a single attachment to a model.
class Attached::One < Attached class Attached::One < Attached
delegate_missing_to :attachment delegate_missing_to :attachment, allow_nil: true
# Returns the associated attachment record. # Returns the associated attachment record.
# #

View file

@ -1,3 +1,9 @@
* `delegate_missing_to` would raise a `DelegationError` if the object
delegated to was `nil`. Now the `allow_nil` option has been added to enable
the user to specify they want `nil` returned in this case.
*Matthew Tanous*
* `truncate` would return the original string if it was too short to be truncated * `truncate` would return the original string if it was too short to be truncated
and a frozen string if it were long enough to be truncated. Now truncate will and a frozen string if it were long enough to be truncated. Now truncate will
consistently return an unfrozen string regardless. This behavior is consistent consistently return an unfrozen string regardless. This behavior is consistent
@ -19,5 +25,4 @@
*Jordan Thomas* *Jordan Thomas*
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activesupport/CHANGELOG.md) for previous changes. Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activesupport/CHANGELOG.md) for previous changes.

View file

@ -274,8 +274,9 @@ class Module
# variables, methods, constants, etc. # variables, methods, constants, etc.
# #
# The delegated method must be public on the target, otherwise it will # The delegated method must be public on the target, otherwise it will
# raise +NoMethodError+. # raise +DelegationError+. If you wish to instead return +nil+,
def delegate_missing_to(target) # use the <tt>:allow_nil</tt> option.
def delegate_missing_to(target, allow_nil: nil)
target = target.to_s target = target.to_s
target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target) target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target)
@ -295,7 +296,11 @@ class Module
super super
rescue NoMethodError rescue NoMethodError
if #{target}.nil? if #{target}.nil?
if #{allow_nil == true}
return nil
else
raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil" raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil"
end
else else
raise raise
end end

View file

@ -92,6 +92,16 @@ DecoratedTester = Struct.new(:client) do
delegate_missing_to :client delegate_missing_to :client
end end
class DecoratedMissingAllowNil
delegate_missing_to :case, allow_nil: true
attr_reader :case
def initialize(kase)
@case = kase
end
end
class DecoratedReserved class DecoratedReserved
delegate_missing_to :case delegate_missing_to :case
@ -382,6 +392,10 @@ class ModuleTest < ActiveSupport::TestCase
assert_equal "name delegated to client, but client is nil", e.message assert_equal "name delegated to client, but client is nil", e.message
end end
def test_delegate_missing_to_returns_nil_if_allow_nil_and_nil_target
assert_nil DecoratedMissingAllowNil.new(nil).name
end
def test_delegate_missing_to_affects_respond_to def test_delegate_missing_to_affects_respond_to
assert_respond_to DecoratedTester.new(@david), :name assert_respond_to DecoratedTester.new(@david), :name
assert_not_respond_to DecoratedTester.new(@david), :private_name assert_not_respond_to DecoratedTester.new(@david), :private_name