Skip to content

Commit 4b0ea7f

Browse files
DmitryTsepelevLeFnord
authored andcommitted
Allow replace non-conditional non-nesting exposures in child classes (fixes #286) (#292)
1 parent 65d7650 commit 4b0ea7f

File tree

6 files changed

+35
-18
lines changed

6 files changed

+35
-18
lines changed

.rubocop_todo.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Metrics/AbcSize:
1818
# Offense count: 35
1919
# Configuration parameters: CountComments, ExcludedMethods.
2020
Metrics/BlockLength:
21-
Max: 1489
21+
Max: 1496
2222

2323
# Offense count: 2
2424
# Configuration parameters: CountComments.

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
#### Fixes
1515

1616
* [#288](https://github.com/ruby-grape/grape-entity/pull/288) Fix wrong argument exception when &:block passed to the expose method - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
17-
* [#291](https://github.com/ruby-grape/grape-entity/pull/291) Refactor and simplify various classes and modules
17+
* [#291](https://github.com/ruby-grape/grape-entity/pull/291) Refactor and simplify various classes and modules - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
18+
* [#292](https://github.com/ruby-grape/grape-entity/pull/292): Allow replace non-conditional non-nesting exposures in child classes (fixes [#286](https://github.com/ruby-grape/grape-entity/issues/286)) - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
1819
* Your contribution here.
1920

2021
### 0.6.1 (2017-01-09)

lib/grape_entity/entity.rb

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -185,25 +185,24 @@ def self.expose(*args, &block)
185185

186186
@documentation = nil
187187
@nesting_stack ||= []
188+
args.each { |attribute| build_exposure_for_attribute(attribute, @nesting_stack, options, block) }
189+
end
188190

189-
# rubocop:disable Style/Next
190-
args.each do |attribute|
191-
exposure = Exposure.new(attribute, options)
191+
def self.build_exposure_for_attribute(attribute, nesting_stack, options, block)
192+
exposure_list = nesting_stack.empty? ? root_exposures : nesting_stack.last.nested_exposures
192193

193-
if @nesting_stack.empty?
194-
root_exposures << exposure
195-
else
196-
@nesting_stack.last.nested_exposures << exposure
197-
end
194+
exposure = Exposure.new(attribute, options)
198195

199-
# Nested exposures are given in a block with no parameters.
200-
if exposure.nesting?
201-
@nesting_stack << exposure
202-
block.call
203-
@nesting_stack.pop
204-
end
205-
end
206-
# rubocop:enable Style/Next
196+
exposure_list.delete_by(attribute) if exposure_list.select_by(attribute).all? { |exp| exp.replaceable_by?(exposure) }
197+
198+
exposure_list << exposure
199+
200+
# Nested exposures are given in a block with no parameters.
201+
return unless exposure.nesting?
202+
203+
nesting_stack << exposure
204+
block.call
205+
nesting_stack.pop
207206
end
208207

209208
# Returns exposures that have been declared for this Entity on the top level.

lib/grape_entity/exposure/base.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ def with_attr_path(entity, options)
116116
end
117117
end
118118

119+
def replaceable_by?(other)
120+
!nesting? && !conditional? && !other.nesting? && !other.conditional?
121+
end
122+
119123
protected
120124

121125
attr_reader :options

lib/grape_entity/exposure/nesting_exposure/nested_exposures.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ def find_by(attribute)
1616
@exposures.find { |e| e.attribute == attribute }
1717
end
1818

19+
def select_by(attribute)
20+
@exposures.select { |e| e.attribute == attribute }
21+
end
22+
1923
def <<(exposure)
2024
reset_memoization!
2125
@exposures << exposure

spec/grape_entity/entity_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,15 @@ class Parent < Person
352352
expect(subject.represent({ name: 'bar' }, serializable: true)).to eq(email: nil, name: 'bar')
353353
expect(child_class.represent({ name: 'bar' }, serializable: true)).to eq(email: nil, name: 'foo')
354354
end
355+
356+
it 'overrides parent class exposure' do
357+
subject.expose :name
358+
child_class = Class.new(subject)
359+
child_class.expose :name, as: :child_name
360+
361+
expect(subject.represent({ name: 'bar' }, serializable: true)).to eq(name: 'bar')
362+
expect(child_class.represent({ name: 'bar' }, serializable: true)).to eq(child_name: 'bar')
363+
end
355364
end
356365

357366
context 'register formatters' do

0 commit comments

Comments
 (0)