Skip to content

Commit

Permalink
Refactoring: extract exposures.
Browse files Browse the repository at this point in the history
This one reaches many goals at once:

 - Fixes ruby-grape#56.
 - `exposures` hash table is removed and substituted with
   `root_exposures` array.
 - Due to previous point, tree structure `nested_exposures` based on
   flat hash table with keys like `root_node__node__node` is removed
   because now double exposures don't rewrite previously defined
   so such tree structure is simply incorrect.
   `NestingExposure` with an array of children is introduced instead.
 - Ones who want an old rewriting behavior should manually `unexpose`.
 - Fixes ruby-grape#112.
 - Fixes ruby-grape#149: runtime `options` are now wrapped in an `Options` object.
 - Fixes ruby-grape#150: see new `spec/grape_entity/exposure_spec.rb`.
 - Fixes ruby-grape#152.
 - Fixes ruby-grape#153.
 - Fixes ruby-grape#155.
 - Fixes ruby-grape#156.
 - All exposure configuration and exposing strategies are extracted to
   the separate classes.
 - `key_for`, `name_for` internal methods are removed.
 - Much of the overhead is gone so performance is increased by 20-30%.

Version is bumbed to 0.5.0.
  • Loading branch information
marshall-lee committed Jul 24, 2015
1 parent a4aa641 commit be25713
Show file tree
Hide file tree
Showing 20 changed files with 1,114 additions and 376 deletions.
19 changes: 15 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,21 @@
* [#134](https://github.com/intridea/grape-entity/pull/134): Subclasses no longer affected in all cases by `unexpose` in parent - [@etehtsea](https://github.com/etehtsea).
* [#135](https://github.com/intridea/grape-entity/pull/135): Added `except` option - [@dan-corneanu](https://github.com/dan-corneanu).
* [#136](https://github.com/intridea/grape-entity/pull/136): Allow for strings in `only` and `except` options - [@bswinnerton](https://github.com/bswinnerton).
* [#147](https://github.com/intridea/grape-entity/pull/147): Expose `safe` attributes as `nil` if they cannot be evaluated: [#140](https://github.com/intridea/grape-entity/issues/140).
* [#147](https://github.com/intridea/grape-entity/pull/147): Fix: private method values were not exposed with `safe` option: [#142](https://github.com/intridea/grape-entity/pull/142).
* [#147](https://github.com/intridea/grape-entity/pull/147): Remove catching of `NoMethodError` because it can occur deep inside in a method call so this exception does not mean that attribute not exist.
* [#147](https://github.com/intridea/grape-entity/pull/147): `valid_exposures` is removed.
* [#147](https://github.com/intridea/grape-entity/pull/147): Expose `safe` attributes as `nil` if they cannot be evaluated: [#140](https://github.com/intridea/grape-entity/issues/140) - [@marshall-lee](https://github.com/marshall-lee).
* [#147](https://github.com/intridea/grape-entity/pull/147): Fix: private method values were not exposed with `safe` option: [#142](https://github.com/intridea/grape-entity/pull/142) - [@marshall-lee](https://github.com/marshall-lee).
* [#147](https://github.com/intridea/grape-entity/pull/147): Remove catching of `NoMethodError` because it can occur deep inside in a method call so this exception does not mean that attribute not exist - [@marshall-lee](https://github.com/marshall-lee).
* [#147](https://github.com/intridea/grape-entity/pull/147): `valid_exposures` is removed - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): `.exposures` is removed and substituted with `.root_exposures` array - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): `.nested_exposures` is removed too - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): `#should_return_attribute?`, `#only_fields` and `#except_fields` are moved to other classes - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): Fix: double exposures with conditions does not rewrite previously defined now: [#56](https://github.com/intridea/grape-entity/issues/56) - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): Fix: nested exposures were flattened in `.documentation`: [#112](https://github.com/intridea/grape-entity/issues/112) - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): Fix: `@only_fields` and `@except_fields` memoization: [#149](https://github.com/intridea/grape-entity/issues/149) - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): Fix: `:unless` condition with `Hash` argument logic: [#150](https://github.com/intridea/grape-entity/issues/150) - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): Nested `unexpose` now raises an exception: [#152](https://github.com/intridea/grape-entity/issues/152) - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): Fix: `@documentation` memoization: [#153](https://github.com/intridea/grape-entity/issues/153) - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): Fix: serializing of deeply nested presenter exposures: [#155](https://github.com/intridea/grape-entity/issues/155) - [@marshall-lee](https://github.com/marshall-lee).
* [#151](https://github.com/intridea/grape-entity/pull/151): Fix: deep projections (`:only`, `:except`) were unaware of nesting: [#156](https://github.com/intridea/grape-entity/issues/156) - [@marshall-lee](https://github.com/marshall-lee).
* Your contribution here.

0.4.5 (2015-03-10)
Expand Down
2 changes: 2 additions & 0 deletions lib/grape_entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
require 'grape_entity/version'
require 'grape_entity/entity'
require 'grape_entity/delegator'
require 'grape_entity/exposure'
require 'grape_entity/options'
26 changes: 26 additions & 0 deletions lib/grape_entity/condition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'grape_entity/condition/base'
require 'grape_entity/condition/block_condition'
require 'grape_entity/condition/hash_condition'
require 'grape_entity/condition/symbol_condition'

module Grape
class Entity
module Condition
def self.new_if(arg)
case arg
when Hash then HashCondition.new false, arg
when Proc then BlockCondition.new false, &arg
when Symbol then SymbolCondition.new false, arg
end
end

def self.new_unless(arg)
case arg
when Hash then HashCondition.new true, arg
when Proc then BlockCondition.new true, &arg
when Symbol then SymbolCondition.new true, arg
end
end
end
end
end
35 changes: 35 additions & 0 deletions lib/grape_entity/condition/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Grape
class Entity
module Condition
class Base
def self.new(inverse, *args, &block)
super(inverse).tap { |e| e.setup(*args, &block) }
end

def initialize(inverse = false)
@inverse = inverse
end

def ==(other)
(self.class == other.class) && (self.inversed? == other.inversed?)
end

def inversed?
@inverse
end

def met?(entity, options)
!@inverse ? if_value(entity, options) : unless_value(entity, options)
end

def if_value(_entity, _options)
fail NotImplementedError
end

def unless_value(entity, options)
!if_value(entity, options)
end
end
end
end
end
21 changes: 21 additions & 0 deletions lib/grape_entity/condition/block_condition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Grape
class Entity
module Condition
class BlockCondition < Base
attr_reader :block

def setup(&block)
@block = block
end

def ==(other)
super && @block == other.block
end

def if_value(entity, options)
entity.exec_with_object(options, &@block)
end
end
end
end
end
25 changes: 25 additions & 0 deletions lib/grape_entity/condition/hash_condition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Grape
class Entity
module Condition
class HashCondition < Base
attr_reader :cond_hash

def setup(cond_hash)
@cond_hash = cond_hash
end

def ==(other)
super && @cond_hash == other.cond_hash
end

def if_value(_entity, options)
@cond_hash.all? { |k, v| options[k.to_sym] == v }
end

def unless_value(_entity, options)
@cond_hash.any? { |k, v| options[k.to_sym] != v }
end
end
end
end
end
21 changes: 21 additions & 0 deletions lib/grape_entity/condition/symbol_condition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Grape
class Entity
module Condition
class SymbolCondition < Base
attr_reader :symbol

def setup(symbol)
@symbol = symbol
end

def ==(other)
super && @symbol == other.symbol
end

def if_value(_entity, options)
options[symbol]
end
end
end
end
end
Loading

0 comments on commit be25713

Please sign in to comment.