Skip to content

Commit

Permalink
Introduce override option for expose (#297)
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitryTsepelev authored and LeFnord committed Jan 29, 2018
1 parent 0890ceb commit 391bff6
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Metrics/AbcSize:
# Offense count: 35
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Max: 1625
Max: 1632

# Offense count: 2
# Configuration parameters: CountComments.
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#### Features

* [#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).
* Your contribution here.

#### Fixes
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,22 @@ class MailingAddress < UserData
end
```

#### Overriding exposures

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:

```ruby
class User < Grape::Entity
expose :name
end

class Employee < UserData
expose :name, as: :employee_name, override: true
end
```

`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" }`.

#### Returning only the fields you want

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:
Expand Down
4 changes: 2 additions & 2 deletions lib/grape_entity/entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def self.build_exposure_for_attribute(attribute, nesting_stack, options, block)

exposure = Exposure.new(attribute, options)

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

exposure_list << exposure

Expand Down Expand Up @@ -527,7 +527,7 @@ def to_xml(options = {})

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

# Merges the given options with current block options.
Expand Down
7 changes: 4 additions & 3 deletions lib/grape_entity/exposure/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Grape
class Entity
module Exposure
class Base
attr_reader :attribute, :is_safe, :documentation, :conditions, :for_merge
attr_reader :attribute, :is_safe, :documentation, :override, :conditions, :for_merge

def self.new(attribute, options, conditions, *args, &block)
super(attribute, options, conditions).tap { |e| e.setup(*args, &block) }
Expand All @@ -19,6 +19,7 @@ def initialize(attribute, options, conditions)
@for_merge = options[:merge]
@attr_path_proc = options[:attr_path]
@documentation = options[:documentation]
@override = options[:override]
@conditions = conditions
end

Expand Down Expand Up @@ -116,8 +117,8 @@ def with_attr_path(entity, options)
end
end

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

protected
Expand Down
11 changes: 10 additions & 1 deletion spec/grape_entity/entity_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -477,11 +477,20 @@ class Parent < Person
expect(child_class.represent({ name: 'bar' }, serializable: true)).to eq(email: nil, name: 'foo')
end

it 'overrides parent class exposure' do
it 'not overrides exposure by default' 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(name: 'bar', child_name: 'bar')
end

it 'overrides parent class exposure when option is specified' do
subject.expose :name
child_class = Class.new(subject)
child_class.expose :name, as: :child_name, override: true

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
Expand Down

0 comments on commit 391bff6

Please sign in to comment.