Skip to content

Commit

Permalink
Improved nested exposures performance, nested exposures doubling fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
AMar4enko committed Feb 28, 2014
1 parent b8c4fe4 commit 912cd59
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
18 changes: 16 additions & 2 deletions lib/grape_entity/entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,13 @@ def self.expose(*args, &block)
options[:proc] = block if block_given? && block.parameters.any?

@nested_attributes ||= []

args.each do |attribute|
unless @nested_attributes.empty?
attribute = "#{@nested_attributes.last}__#{attribute}"
options[:nested] = true
nested_exposures[@nested_attributes.last.to_sym] ||= {}
nested_exposures[@nested_attributes.last.to_sym][attribute.to_sym] = options
end

exposures[attribute.to_sym] = options
Expand Down Expand Up @@ -180,6 +184,16 @@ def self.exposures
@exposures
end

def self.nested_exposures
@nested_exposures ||= {}

if superclass.respond_to? :nested_exposures
@nested_exposures = superclass.nested_exposures.merge(@nested_exposures)
end

@nested_exposures
end

# Returns a hash, the keys are symbolized references to fields in the entity,
# the values are document keys in the entity's documentation key. When calling
# #docmentation, any exposure without a documentation key will be ignored.
Expand Down Expand Up @@ -324,7 +338,7 @@ def exposures
end

def valid_exposures
exposures.select do |attribute, exposure_options|
exposures.reject{|a, options| options[:nested]}.select do |attribute, exposure_options|
valid_exposure?(attribute, exposure_options)
end
end
Expand Down Expand Up @@ -390,7 +404,7 @@ def self.key_for(attribute)
end

def self.nested_exposures_for(attribute)
exposures.select { |a, _| a.to_s =~ /^#{attribute}__/ }
nested_exposures[attribute] || {}
end

def value_for(attribute, options = {})
Expand Down
28 changes: 25 additions & 3 deletions spec/grape_entity/entity_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ class BogusEntity < Grape::Entity

subject.exposures.should == {
awesome: {},
awesome__nested: {},
awesome__nested__moar_nested: { as: 'weee' },
awesome__another_nested: { using: 'Awesome' }
awesome__nested: {:nested => true},
awesome__nested__moar_nested: { as: 'weee', :nested => true },
awesome__another_nested: { using: 'Awesome', :nested => true }
}
end

Expand All @@ -110,6 +110,27 @@ class BogusEntity < Grape::Entity
}
end

it 'not represents attributes, declared inside nested exposure, outside of it' do
subject.expose :awesome do
subject.expose(:nested) { |_| "value" }
subject.expose(:another_nested) { |_| "value" }
subject.expose :second_level_nested do
subject.expose(:deeply_exposed_attr) { |_| "value" }
end
end

subject.represent({}).serializable_hash.should == {
awesome: {
nested: "value",
another_nested: "value",
second_level_nested: {
deeply_exposed_attr: "value"
}
}
}
end


it 'is safe if its nested exposures are safe' do
subject.with_options safe: true do
subject.expose :awesome do
Expand All @@ -121,6 +142,7 @@ class BogusEntity < Grape::Entity
end

valid_keys = subject.represent({}).valid_exposures.keys

valid_keys.include?(:awesome).should == true && \
valid_keys.include?(:not_awesome).should == false
end
Expand Down

0 comments on commit 912cd59

Please sign in to comment.