Skip to content

Commit 54403a4

Browse files
committed
Merged #16.
2 parents 047d1c1 + 43b6439 commit 54403a4

File tree

4 files changed

+95
-5
lines changed

4 files changed

+95
-5
lines changed

CHANGELOG.markdown

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Next Release
33
* Ruby 1.8.x is no longer supported - [@dblock](https://github.com/dblock).
44
* [#7](https://github.com/intridea/grape-entity/issues/7): Add `serializable` option to `represent` - [@mbleigh](https://github.com/mbleigh).
55
* [#18](https://github.com/intridea/grape-entity/pull/18): Add `safe` option to `expose`, will not raise error for a missing attribute - [@fixme](https://github.com/fixme).
6+
* [#16](https://github.com/intridea/grape-entity/pull/16): Add `:using` option to `expose SYMBOL BLOCK` - [@fahchen](https://github.com/fahchen).
67
* Your contribution here.
78

89
0.3.0 (2013-03-29)

README.markdown

+6-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ array.
4141
* `expose SYMBOL, { :as => "alias" }`
4242
* Expose a value, changing its hash key from SYMBOL to alias
4343
* `:as` can only be applied to one exposure at a time
44-
* `expose SYMBOL BLOCK`
44+
* `expose SYMBOL, HASH BLOCK`
45+
* HASH keys only can be `:using`
4546
* block arguments are object and options
46-
* expose the value returned by the block
47+
* expose the value returned by the block (and present by `:using` option)
4748
* block can only be applied to one exposure at a time
4849
* `with_options HASH BLOCK`
4950
* exposures defined within a `with_options` block will inherit any options defined in HASH. Same keys available as `expose SYMBOLS, HASH`
@@ -62,6 +63,9 @@ module API
6263
Digest::MD5.hexdigest status.txt
6364
end
6465
expose :replies, :using => API::Status, :as => :replies
66+
expose :last_reply, :using => API::Status do |status, options|
67+
status.replies.last
68+
end
6569

6670
with_options({ :format_with => :iso_timestamp }) do
6771
expose :created_at

lib/grape_entity/entity.rb

+8-1
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,14 @@ def value_for(attribute, options = {})
374374
exposure_options = exposures[attribute.to_sym]
375375

376376
if exposure_options[:proc]
377-
exposure_options[:proc].call(object, options)
377+
if exposure_options[:using]
378+
using_options = options.dup
379+
using_options.delete(:collection)
380+
using_options[:root] = nil
381+
exposure_options[:using].represent(exposure_options[:proc].call(object, options), using_options)
382+
else
383+
exposure_options[:proc].call(object, options)
384+
end
378385
elsif exposure_options[:using]
379386
using_options = options.dup
380387
using_options.delete(:collection)

spec/grape_entity/entity_spec.rb

+80-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939

4040
it 'sets the :proc option in the exposure options' do
4141
block = lambda{|_| true }
42-
subject.expose :name, &block
43-
subject.exposures[:name][:proc].should == block
42+
subject.expose :name, :using => 'Awesome', &block
43+
subject.exposures[:name].should == { :proc => block, :using => 'Awesome' }
4444
end
4545
end
4646

@@ -358,6 +358,27 @@
358358
end
359359
end
360360

361+
it "exposes attributes that don't exist on the object only when they are generated by a block with options" do
362+
module EntitySpec
363+
class TestEntity < Grape::Entity
364+
end
365+
end
366+
367+
fresh_class.expose :nonexistent_attribute, using: EntitySpec::TestEntity do |model, _|
368+
"well, I do exist after all"
369+
end
370+
res = fresh_class.new(model).serializable_hash
371+
res.should have_key :nonexistent_attribute
372+
end
373+
374+
it "does not expose attributes that are generated by a block but have not passed criteria" do
375+
fresh_class.expose :nonexistent_attribute, :proc => lambda {|model, _|
376+
"I exist, but it is not yet my time to shine"
377+
}, :if => lambda { |model, _| false }
378+
res = fresh_class.new(model).serializable_hash
379+
res.should_not have_key :nonexistent_attribute
380+
end
381+
361382
context '#serializable_hash' do
362383

363384
module EntitySpec
@@ -451,6 +472,63 @@ class FriendEntity < Grape::Entity
451472
rep.last.serializable_hash[:name].should == 'Friend 2'
452473
end
453474

475+
it "passes through the proc which returns an array of objects with custom options(:using)" do
476+
module EntitySpec
477+
class FriendEntity < Grape::Entity
478+
root 'friends', 'friend'
479+
expose :name, :email
480+
end
481+
end
482+
483+
fresh_class.class_eval do
484+
expose :custom_friends, :using => EntitySpec::FriendEntity do |user, options|
485+
user.friends
486+
end
487+
end
488+
489+
rep = subject.send(:value_for, :custom_friends)
490+
rep.should be_kind_of Array
491+
rep.reject{|r| r.is_a?(EntitySpec::FriendEntity)}.should be_empty
492+
rep.first.serializable_hash.should == { :name => 'Friend 1', :email => '[email protected]'}
493+
rep.last.serializable_hash.should == { :name => 'Friend 2', :email => '[email protected]'}
494+
end
495+
it "passes through the proc which returns single object with custom options(:using)" do
496+
module EntitySpec
497+
class FriendEntity < Grape::Entity
498+
root 'friends', 'friend'
499+
expose :name, :email
500+
end
501+
end
502+
503+
fresh_class.class_eval do
504+
expose :first_friend, :using => EntitySpec::FriendEntity do |user, options|
505+
user.friends.first
506+
end
507+
end
508+
509+
rep = subject.send(:value_for, :first_friend)
510+
rep.should be_kind_of EntitySpec::FriendEntity
511+
rep.serializable_hash.should == { :name => 'Friend 1', :email => '[email protected]'}
512+
end
513+
it "passes through the proc which returns empty with custom options(:using)" do
514+
module EntitySpec
515+
class FriendEntity < Grape::Entity
516+
root 'friends', 'friend'
517+
expose :name, :email
518+
end
519+
end
520+
521+
fresh_class.class_eval do
522+
expose :first_friend, :using => EntitySpec::FriendEntity do |user, options|
523+
524+
end
525+
end
526+
527+
rep = subject.send(:value_for, :first_friend)
528+
rep.should be_kind_of EntitySpec::FriendEntity
529+
rep.serializable_hash.should be_nil
530+
end
531+
454532
it 'passes through custom options' do
455533
module EntitySpec
456534
class FriendEntity < Grape::Entity

0 commit comments

Comments
 (0)