Skip to content

Commit

Permalink
Define respond_to? on RecordRef to match method_missing behavior
Browse files Browse the repository at this point in the history
`RecordRef`s often include a name, which allows access via
`method_missing` by calling `record_ref.name`, however if no referenced
record is assigned, you'll still get a `RecordRef` instance, it just
wont have any fields, so `record_ref.name` raised a `NoMethodError`, but
if you checked for the field first via `record_ref.respond_to?(:name)`,
it'd be falsey regardless of whether the field existed or not.

Defining `respond_to?` in good practice alongside `method_missing`.
Ideally, `respond_to_missing?` would be used instead, as that enables
access to the method like `record_ref.method(:name)`, however I kept
with `respond_to?` to match `CustomFieldList`.

`CustomRecordRef` also uses `method_missing`, however there's no specs
and I'm not familiar with that record, so I left it alone.
  • Loading branch information
cgunther committed Mar 7, 2024
1 parent dd693a3 commit 9e74b12
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 0 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

### Fixed
* Revert recent proxy changes which breaks proxy usage by @andrewdicken-stripe in https://github.com/NetSweet/netsuite/pull/579
* Define `respond_to?` on `RecordRef` to match `method_missing` behavior (#608)

### Breaking Changes

Expand Down
5 changes: 5 additions & 0 deletions lib/netsuite/records/record_ref.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ def method_missing(m, *args, &block)
end
end

def respond_to?(m, include_private = false)
return true if attributes.keys.map(&:to_sym).include?(m.to_sym)
super
end

end
end
end
8 changes: 8 additions & 0 deletions spec/netsuite/records/record_ref_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,16 @@

context 'readers' do
it 'can take on arbitrary attributes into itself on initialization' do
expect(record_ref).to respond_to(:name)
expect(record_ref).to respond_to('name')
expect(record_ref.name).to eql('This is a record_ref')

expect(record_ref).to respond_to(:banana)
expect(record_ref).to respond_to('banana')
expect(record_ref.banana).to eql('for monkeys')

expect(record_ref).to_not respond_to(:non_existant_field)
expect(record_ref).to_not respond_to('non_existant_field')
end
end
end
Expand Down

0 comments on commit 9e74b12

Please sign in to comment.