Skip to content

Commit 391bff6

Browse files
DmitryTsepelevLeFnord
authored andcommitted
Introduce override option for expose (#297)
1 parent 0890ceb commit 391bff6

File tree

6 files changed

+34
-7
lines changed

6 files changed

+34
-7
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: 1625
21+
Max: 1632
2222

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

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#### Features
44

5+
* [#292](https://github.com/ruby-grape/grape-entity/pull/297): Introduce `override` option for expose (fixes [#286](https://github.com/ruby-grape/grape-entity/issues/296)) - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
56
* Your contribution here.
67

78
#### Fixes

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,22 @@ class MailingAddress < UserData
256256
end
257257
```
258258

259+
#### Overriding exposures
260+
261+
If you want to add one more exposure for the field but don't want the first one to be fired (for instance, when using inheritance), you can use the `override` flag. For instance:
262+
263+
```ruby
264+
class User < Grape::Entity
265+
expose :name
266+
end
267+
268+
class Employee < UserData
269+
expose :name, as: :employee_name, override: true
270+
end
271+
```
272+
273+
`User` will return something like this `{ "name" : "John" }` while `Employee` will present the same data as `{ "employee_name" : "John" }` instead of `{ "name" : "John", "employee_name" : "John" }`.
274+
259275
#### Returning only the fields you want
260276

261277
After exposing the desired attributes, you can choose which one you need when representing some object or collection by using the only: and except: options. See the example:

lib/grape_entity/entity.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def self.build_exposure_for_attribute(attribute, nesting_stack, options, block)
197197

198198
exposure = Exposure.new(attribute, options)
199199

200-
exposure_list.delete_by(attribute) if exposure_list.select_by(attribute).all? { |exp| exp.replaceable_by?(exposure) }
200+
exposure_list.delete_by(attribute) if exposure.override?
201201

202202
exposure_list << exposure
203203

@@ -527,7 +527,7 @@ def to_xml(options = {})
527527

528528
# All supported options.
529529
OPTIONS = %i[
530-
rewrite as if unless using with proc documentation format_with safe attr_path if_extras unless_extras merge expose_nil
530+
rewrite as if unless using with proc documentation format_with safe attr_path if_extras unless_extras merge expose_nil override
531531
].to_set.freeze
532532

533533
# Merges the given options with current block options.

lib/grape_entity/exposure/base.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module Grape
44
class Entity
55
module Exposure
66
class Base
7-
attr_reader :attribute, :is_safe, :documentation, :conditions, :for_merge
7+
attr_reader :attribute, :is_safe, :documentation, :override, :conditions, :for_merge
88

99
def self.new(attribute, options, conditions, *args, &block)
1010
super(attribute, options, conditions).tap { |e| e.setup(*args, &block) }
@@ -19,6 +19,7 @@ def initialize(attribute, options, conditions)
1919
@for_merge = options[:merge]
2020
@attr_path_proc = options[:attr_path]
2121
@documentation = options[:documentation]
22+
@override = options[:override]
2223
@conditions = conditions
2324
end
2425

@@ -116,8 +117,8 @@ def with_attr_path(entity, options)
116117
end
117118
end
118119

119-
def replaceable_by?(other)
120-
!nesting? && !conditional? && !other.nesting? && !other.conditional?
120+
def override?
121+
@override
121122
end
122123

123124
protected

spec/grape_entity/entity_spec.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,11 +477,20 @@ class Parent < Person
477477
expect(child_class.represent({ name: 'bar' }, serializable: true)).to eq(email: nil, name: 'foo')
478478
end
479479

480-
it 'overrides parent class exposure' do
480+
it 'not overrides exposure by default' do
481481
subject.expose :name
482482
child_class = Class.new(subject)
483483
child_class.expose :name, as: :child_name
484484

485+
expect(subject.represent({ name: 'bar' }, serializable: true)).to eq(name: 'bar')
486+
expect(child_class.represent({ name: 'bar' }, serializable: true)).to eq(name: 'bar', child_name: 'bar')
487+
end
488+
489+
it 'overrides parent class exposure when option is specified' do
490+
subject.expose :name
491+
child_class = Class.new(subject)
492+
child_class.expose :name, as: :child_name, override: true
493+
485494
expect(subject.represent({ name: 'bar' }, serializable: true)).to eq(name: 'bar')
486495
expect(child_class.represent({ name: 'bar' }, serializable: true)).to eq(child_name: 'bar')
487496
end

0 commit comments

Comments
 (0)