Skip to content

Commit 61e5cf9

Browse files
committed
Merge pull request #43 from wellthie/master
Call procs in context of entity instance
2 parents f72f411 + a4d0127 commit 61e5cf9

File tree

4 files changed

+63
-13
lines changed

4 files changed

+63
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ tmp
3636
.rbx
3737

3838
## PROJECT::SPECIFIC
39+
.project

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
Next Release
22
============
33
* Ruby 1.8.x is no longer supported - [@dblock](https://github.com/dblock).
4-
* [#36](https://github.com/intridea/grape-entity/pull/35): Enforcing Ruby style guidelines via Rubocop - [@dblock](https://github.com/dblock).
4+
* [#36](https://github.com/intridea/grape-entity/pull/36): Enforcing Ruby style guidelines via Rubocop - [@dblock](https://github.com/dblock).
55
* [#7](https://github.com/intridea/grape-entity/issues/7): Added `serializable` option to `represent` - [@mbleigh](https://github.com/mbleigh).
66
* [#18](https://github.com/intridea/grape-entity/pull/18): Added `safe` option to `expose`, will not raise error for a missing attribute - [@fixme](https://github.com/fixme).
77
* [#16](https://github.com/intridea/grape-entity/pull/16): Added `using` option to `expose SYMBOL BLOCK` - [@fahchen](https://github.com/fahchen).
88
* [#24](https://github.com/intridea/grape-entity/pull/24): Return documentation with `as` param considered - [@drakula2k](https://github.com/drakula2k).
99
* [#27](https://github.com/intridea/grape-entity/pull/27): Properly serialize hashes - [@clintonb](https://github.com/clintonb).
1010
* [#28](https://github.com/intridea/grape-entity/pull/28): Look for method on entity before calling it on the object - [@MichaelXavier](https://github.com/MichaelXavier).
1111
* [#33](https://github.com/intridea/grape-entity/pull/33): Support proper merging of nested conditionals - [@wyattisimo](https://github.com/wyattisimo).
12+
* [#43](https://github.com/intridea/grape-entity/pull/43): Call procs in context of entity instance - [@joelvh](https://github.com/joelvh).
1213
* Your contribution here.
1314

1415
0.3.0 (2013-03-29)

lib/grape_entity/entity.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,9 @@ def self.exposures
171171
# the values are document keys in the entity's documentation key. When calling
172172
# #docmentation, any exposure without a documentation key will be ignored.
173173
def self.documentation
174-
@documentation ||= exposures.inject({}) do |memo, value|
175-
unless value[1][:documentation].nil? || value[1][:documentation].empty?
176-
memo[key_for(value[0])] = value[1][:documentation]
174+
@documentation ||= exposures.inject({}) do |memo, (attribute, exposure_options)|
175+
unless exposure_options[:documentation].nil? || exposure_options[:documentation].empty?
176+
memo[key_for(attribute)] = exposure_options[:documentation]
177177
end
178178
memo
179179
end
@@ -286,7 +286,7 @@ def self.root(plural, singular = nil)
286286
# even if one is defined for the entity.
287287
def self.represent(objects, options = {})
288288
if objects.respond_to?(:to_ary)
289-
inner = objects.to_ary.map { |o| new(o, { collection: true }.merge(options)) }
289+
inner = objects.to_ary.map { |object| new(object, { collection: true }.merge(options)) }
290290
inner = inner.map(&:serializable_hash) if options[:serializable]
291291
else
292292
inner = new(objects, options)
@@ -380,9 +380,9 @@ def value_for(attribute, options = {})
380380
using_options = options.dup
381381
using_options.delete(:collection)
382382
using_options[:root] = nil
383-
exposure_options[:using].represent(exposure_options[:proc].call(object, options), using_options)
383+
exposure_options[:using].represent(instance_exec(object, options, &exposure_options[:proc]), using_options)
384384
else
385-
exposure_options[:proc].call(object, options)
385+
instance_exec(object, options, &exposure_options[:proc])
386386
end
387387
elsif exposure_options[:using]
388388
using_options = options.dup
@@ -393,11 +393,11 @@ def value_for(attribute, options = {})
393393
format_with = exposure_options[:format_with]
394394

395395
if format_with.is_a?(Symbol) && formatters[format_with]
396-
formatters[format_with].call(delegate_attribute(attribute))
396+
instance_exec(delegate_attribute(attribute), &formatters[format_with])
397397
elsif format_with.is_a?(Symbol)
398398
send(format_with, delegate_attribute(attribute))
399399
elsif format_with.respond_to? :call
400-
format_with.call(delegate_attribute(attribute))
400+
instance_exec(delegate_attribute(attribute), &format_with)
401401
end
402402
else
403403
delegate_attribute(attribute)
@@ -425,7 +425,7 @@ def conditions_met?(exposure_options, options)
425425
if_conditions.each do |if_condition|
426426
case if_condition
427427
when Hash then if_condition.each_pair { |k, v| return false if options[k.to_sym] != v }
428-
when Proc then return false unless if_condition.call(object, options)
428+
when Proc then return false unless instance_exec(object, options, &if_condition)
429429
when Symbol then return false unless options[if_condition]
430430
end
431431
end
@@ -436,7 +436,7 @@ def conditions_met?(exposure_options, options)
436436
unless_conditions.each do |unless_condition|
437437
case unless_condition
438438
when Hash then unless_condition.each_pair { |k, v| return false if options[k.to_sym] == v }
439-
when Proc then return false if unless_condition.call(object, options)
439+
when Proc then return false if instance_exec(object, options, &unless_condition)
440440
when Symbol then return false if options[unless_condition]
441441
end
442442
end

spec/grape_entity/entity_spec.rb

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,36 @@
4141
subject.expose :name, using: 'Awesome', &block
4242
subject.exposures[:name].should == { proc: block, using: 'Awesome' }
4343
end
44+
45+
it 'references an instance of the entity without any options' do
46+
subject.expose(:size) { self }
47+
subject.represent(Hash.new).send(:value_for, :size).should be_an_instance_of fresh_class
48+
end
49+
50+
it 'references an instance of the entity with :using option' do
51+
module EntitySpec
52+
class SomeObject1
53+
attr_accessor :prop1
54+
55+
def initialize
56+
@prop1 = "value1"
57+
end
58+
end
59+
60+
class BogusEntity < Grape::Entity
61+
expose :prop1
62+
end
63+
end
64+
65+
subject.expose(:bogus, using: EntitySpec::BogusEntity) { self.object.prop1 = "MODIFIED 2"; self.object }
66+
67+
object = EntitySpec::SomeObject1.new
68+
value = subject.represent(object).send(:value_for, :bogus)
69+
value.should be_instance_of EntitySpec::BogusEntity
70+
71+
prop1 = value.send(:value_for, :prop1)
72+
prop1.should == "MODIFIED 2"
73+
end
4474
end
4575

4676
context 'inherited exposures' do
@@ -101,6 +131,24 @@
101131
model = { birthday: Time.gm(2012, 2, 27) }
102132
subject.new(double(model)).as_json[:birthday].should == '02/27/2012'
103133
end
134+
135+
it 'formats an exposure with a :format_with lambda that returns a value from the entity instance' do
136+
object = Hash.new
137+
138+
subject.expose(:size, format_with: lambda{|value| self.object.class.to_s})
139+
subject.represent(object).send(:value_for, :size).should == object.class.to_s
140+
end
141+
142+
it 'formats an exposure with a :format_with symbol that returns a value from the entity instance' do
143+
subject.format_with :size_formatter do |date|
144+
self.object.class.to_s
145+
end
146+
147+
object = Hash.new
148+
149+
subject.expose(:size, format_with: :size_formatter)
150+
subject.represent(object).send(:value_for, :size).should == object.class.to_s
151+
end
104152
end
105153
end
106154

@@ -190,11 +238,11 @@
190238
it 'should override nested :using option' do
191239
subject.class_eval do
192240
with_options(using: 'Something') do
193-
expose :awesome_thing, using: 'SometingElse'
241+
expose :awesome_thing, using: 'SomethingElse'
194242
end
195243
end
196244

197-
subject.exposures[:awesome_thing].should == { using: 'SometingElse' }
245+
subject.exposures[:awesome_thing].should == { using: 'SomethingElse' }
198246
end
199247

200248
it 'should override nested :proc option' do

0 commit comments

Comments
 (0)