Skip to content

Commit

Permalink
Allow replace non-conditional non-nesting exposures in child classes (f…
Browse files Browse the repository at this point in the history
…ixes #286)
  • Loading branch information
DmitryTsepelev committed Jan 15, 2018
1 parent 65d7650 commit ef38c9e
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 4 deletions.
10 changes: 6 additions & 4 deletions lib/grape_entity/entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,16 @@ def self.expose(*args, &block)

# rubocop:disable Style/Next
args.each do |attribute|
exposure_list = @nesting_stack.empty? ? root_exposures : @nesting_stack.last.nested_exposures

exposure = Exposure.new(attribute, options)

if @nesting_stack.empty?
root_exposures << exposure
else
@nesting_stack.last.nested_exposures << exposure
if exposure_list.select_by(attribute).all? { |exp| exp.replaceable_by?(exposure) }
exposure_list.delete_by(attribute)
end

exposure_list << exposure

# Nested exposures are given in a block with no parameters.
if exposure.nesting?
@nesting_stack << exposure
Expand Down
4 changes: 4 additions & 0 deletions lib/grape_entity/exposure/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ def with_attr_path(entity, options)
end
end

def replaceable_by?(other)
!nesting? && !conditional? && !other.nesting? && !other.conditional?
end

protected

attr_reader :options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def find_by(attribute)
@exposures.find { |e| e.attribute == attribute }
end

def select_by(attribute)
@exposures.select { |e| e.attribute == attribute }
end

def <<(exposure)
reset_memoization!
@exposures << exposure
Expand Down
9 changes: 9 additions & 0 deletions spec/grape_entity/entity_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,15 @@ class Parent < Person
expect(subject.represent({ name: 'bar' }, serializable: true)).to eq(email: nil, name: 'bar')
expect(child_class.represent({ name: 'bar' }, serializable: true)).to eq(email: nil, name: 'foo')
end

it 'overrides parent class exposure' do
subject.expose :name
child_class = Class.new(subject)
child_class.expose :name, as: :child_name

expect(subject.represent({ name: 'bar' }, serializable: true)).to eq(name: 'bar')
expect(child_class.represent({ name: 'bar' }, serializable: true)).to eq(child_name: 'bar')
end
end

context 'register formatters' do
Expand Down

0 comments on commit ef38c9e

Please sign in to comment.