Skip to content

Commit 856c9d0

Browse files
larryzhaodblock
authored andcommitted
Added support for specifying the presenter class in using: in string format.
1 parent dacc671 commit 856c9d0

File tree

5 files changed

+53
-13
lines changed

5 files changed

+53
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Next Release
1111
* [#33](https://github.com/intridea/grape-entity/pull/33): Support proper merging of nested conditionals - [@wyattisimo](https://github.com/wyattisimo).
1212
* [#43](https://github.com/intridea/grape-entity/pull/43): Call procs in context of entity instance - [@joelvh](https://github.com/joelvh).
1313
* [#47](https://github.com/intridea/grape-entity/pull/47): Support nested exposures - [@wyattisimo](https://github.com/wyattisimo).
14+
* [#46](https://github.com/intridea/grape-entity/issues/46), [#50](https://github.com/intridea/grape-entity/pull/50): Added support for specifying the presenter class in `using` in string format - [@larryzhao](https://github.com/larryzhao).
1415
* Your contribution here.
1516

1617
0.3.0 (2013-03-29)

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ Don't derive your model classes from `Grape::Entity`, expose them using a presen
7171
expose :replies, using: API::Status, as: :replies
7272
```
7373

74+
Presenter classes can also be specified in string format, which helps with circular dependencies.
75+
76+
```ruby
77+
expose :replies, using: `API::Status`, as: :replies
78+
```
79+
7480
#### Conditional Exposure
7581

7682
Use `:if` or `:unless` to expose fields conditionally.

lib/grape_entity.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
require "active_support/core_ext"
12
require "grape_entity/version"
23
require "grape_entity/entity"

lib/grape_entity/entity.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ def value_for(attribute, options = {})
398398
nested_exposures = self.class.nested_exposures_for(attribute)
399399

400400
if exposure_options[:using]
401+
exposure_options[:using] = exposure_options[:using].constantize if exposure_options[:using].respond_to? :constantize
402+
401403
using_options = options.dup
402404
using_options.delete(:collection)
403405
using_options[:root] = nil

spec/grape_entity/entity_spec.rb

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class BogusEntity < Grape::Entity
203203
end
204204

205205
describe '.with_options' do
206-
it 'should apply the options to all exposures inside' do
206+
it 'applies the options to all exposures inside' do
207207
subject.class_eval do
208208
with_options(if: { awesome: true }) do
209209
expose :awesome_thing, using: 'Awesome'
@@ -213,7 +213,7 @@ class BogusEntity < Grape::Entity
213213
subject.exposures[:awesome_thing].should == { if: { awesome: true }, using: 'Awesome' }
214214
end
215215

216-
it 'should allow for nested .with_options' do
216+
it 'allows for nested .with_options' do
217217
subject.class_eval do
218218
with_options(if: { awesome: true }) do
219219
with_options(using: 'Something') do
@@ -225,7 +225,7 @@ class BogusEntity < Grape::Entity
225225
subject.exposures[:awesome_thing].should == { if: { awesome: true }, using: 'Something' }
226226
end
227227

228-
it 'should override nested :as option' do
228+
it 'overrides nested :as option' do
229229
subject.class_eval do
230230
with_options(as: :sweet) do
231231
expose :awesome_thing, as: :extra_smooth
@@ -235,7 +235,7 @@ class BogusEntity < Grape::Entity
235235
subject.exposures[:awesome_thing].should == { as: :extra_smooth }
236236
end
237237

238-
it "should merge nested :if option" do
238+
it "merges nested :if option" do
239239
match_proc = lambda { |obj, opts| true }
240240

241241
subject.class_eval do
@@ -260,7 +260,7 @@ class BogusEntity < Grape::Entity
260260
}
261261
end
262262

263-
it 'should merge nested :unless option' do
263+
it 'merges nested :unless option' do
264264
match_proc = lambda { |obj, opts| true }
265265

266266
subject.class_eval do
@@ -285,7 +285,7 @@ class BogusEntity < Grape::Entity
285285
}
286286
end
287287

288-
it 'should override nested :using option' do
288+
it 'overrides nested :using option' do
289289
subject.class_eval do
290290
with_options(using: 'Something') do
291291
expose :awesome_thing, using: 'SomethingElse'
@@ -295,7 +295,7 @@ class BogusEntity < Grape::Entity
295295
subject.exposures[:awesome_thing].should == { using: 'SomethingElse' }
296296
end
297297

298-
it 'should override nested :proc option' do
298+
it 'overrides nested :proc option' do
299299
match_proc = lambda { |obj, opts| 'more awesomer' }
300300

301301
subject.class_eval do
@@ -307,7 +307,7 @@ class BogusEntity < Grape::Entity
307307
subject.exposures[:awesome_thing].should == { proc: match_proc }
308308
end
309309

310-
it 'should override nested :documentation option' do
310+
it 'overrides nested :documentation option' do
311311
subject.class_eval do
312312
with_options(documentation: { desc: 'Description.' }) do
313313
expose :awesome_thing, documentation: { desc: 'Other description.' }
@@ -517,7 +517,7 @@ class BogusEntity < Grape::Entity
517517
end
518518

519519
context "without safe option" do
520-
it 'should throw an exception when an attribute is not found on the object' do
520+
it 'throws an exception when an attribute is not found on the object' do
521521
fresh_class.expose :name, :nonexistent_attribute
522522
expect { fresh_class.new(model).serializable_hash }.to raise_error
523523
end
@@ -651,7 +651,6 @@ def timestamp(date)
651651

652652
context 'child representations' do
653653
it 'disables root key name for child representations' do
654-
655654
module EntitySpec
656655
class FriendEntity < Grape::Entity
657656
root 'friends', 'friend'
@@ -690,6 +689,7 @@ class FriendEntity < Grape::Entity
690689
rep.first.serializable_hash.should == { name: 'Friend 1', email: '[email protected]' }
691690
rep.last.serializable_hash.should == { name: 'Friend 2', email: '[email protected]' }
692691
end
692+
693693
it "passes through the proc which returns single object with custom options(:using)" do
694694
module EntitySpec
695695
class FriendEntity < Grape::Entity
@@ -708,6 +708,7 @@ class FriendEntity < Grape::Entity
708708
rep.should be_kind_of EntitySpec::FriendEntity
709709
rep.serializable_hash.should == { name: 'Friend 1', email: '[email protected]' }
710710
end
711+
711712
it "passes through the proc which returns empty with custom options(:using)" do
712713
module EntitySpec
713714
class FriendEntity < Grape::Entity
@@ -772,7 +773,6 @@ class FriendEntity < Grape::Entity
772773
rep.first.serializable_hash[:email].should == '[email protected]'
773774
rep.last.serializable_hash[:email].should == '[email protected]'
774775
end
775-
776776
end
777777

778778
it 'calls through to the proc if there is one' do
@@ -807,6 +807,37 @@ def name
807807
rep.send(:value_for, :name).should == "cooler name"
808808
rep.send(:value_for, :email).should == "[email protected]"
809809
end
810+
811+
context "using" do
812+
before do
813+
module EntitySpec
814+
class UserEntity < Grape::Entity
815+
expose :name, :email
816+
end
817+
end
818+
end
819+
it "string" do
820+
fresh_class.class_eval do
821+
expose :friends, using: "EntitySpec::UserEntity"
822+
end
823+
824+
rep = subject.send(:value_for, :friends)
825+
rep.should be_kind_of Array
826+
rep.size.should == 2
827+
rep.all? { |r| r.is_a?(EntitySpec::UserEntity) }.should be_true
828+
end
829+
830+
it 'class' do
831+
fresh_class.class_eval do
832+
expose :friends, using: EntitySpec::UserEntity
833+
end
834+
835+
rep = subject.send(:value_for, :friends)
836+
rep.should be_kind_of Array
837+
rep.size.should == 2
838+
rep.all? { |r| r.is_a?(EntitySpec::UserEntity) }.should be_true
839+
end
840+
end
810841
end
811842

812843
describe '#documentation' do
@@ -951,13 +982,12 @@ def name
951982
instance.entity.object.should == instance
952983
end
953984

954-
it 'should instantiate with options if provided' do
985+
it 'instantiates with options if provided' do
955986
instance.entity(awesome: true).options.should == { awesome: true }
956987
end
957988
end
958989
end
959990
end
960991
end
961-
962992
end
963993
end

0 commit comments

Comments
 (0)