-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow for serializing json api resource collections into root key #23
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ def initialize(*args) | |
end | ||
|
||
def type(*types) | ||
@root_name = types.first.to_s | ||
@root_name = types.first.to_s.pluralize.to_sym | ||
end | ||
|
||
def link(rel, opts = {}) | ||
|
@@ -55,12 +55,27 @@ def entities(name, collection, serializer_class = nil, context_options = {}, &bl | |
end | ||
end | ||
|
||
def collection(name, collection, serializer_class = nil, context_options = {}, &block) | ||
@treat_as_resource_collection = true | ||
data[:resource_collection] = [] unless data[:resource_collection].is_a?(Array) | ||
|
||
collection.each do |obj| | ||
ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block) | ||
data[:resource_collection] << ent if ent | ||
end | ||
end | ||
|
||
def to_hash | ||
raise "JSON API entities MUST define a type. Use type 'user' in your serializers" unless root_name | ||
if serializer.top != serializer | ||
return data | ||
else | ||
h = {root_name.pluralize.to_sym => [data]} | ||
h = {} | ||
if @treat_as_resource_collection | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we not just check that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see now that this is needed because of the self-initialized data hash. It's proven handy before but do you think that it forces us to add these workarounds too much? Maybe it doesn't need to auto-initialize missing keys as hashes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do think maybe that it assumes to much about the data structure that will be constructed in the adapters. Keep in mind that not self-initializing the sub hashes pretty much rules out #19 from happening. This would mean possibly Adapter#to_hash or Serializer#to_hash will have to do a recursive deep search to call to_hash on sub serializers if the change is made to Adapter#serializer_from_block_or_class to return serializers and if you still don't want #to_hash being called on these from within the adapter methods. |
||
h[root_name] = data[:resource_collection] | ||
else | ||
h[root_name] = [data] | ||
end | ||
h[:linked] = @entities if @entities.keys.any? | ||
return h | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,5 +97,75 @@ | |
hash.fetch(:linked).fetch(:managers).should be_empty | ||
end | ||
end | ||
|
||
context 'with an entity collection' do | ||
let(:serializer_collection_class) do | ||
USER_SERIALIZER = serializer_class unless defined?(USER_SERIALIZER) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need this? And why a constant? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It gets used on Line 107 to define which serializer to use on the collection. It has to be a constant in this test because you can't pass a locally defined variable into another class definition. |
||
Class.new(Oat::Serializer) do | ||
schema do | ||
type 'users' | ||
collection :users, item, USER_SERIALIZER | ||
end | ||
end | ||
end | ||
|
||
let(:collection_serializer){ | ||
serializer_collection_class.new( | ||
[user,friend], | ||
{:name => "some_controller"}, | ||
Oat::Adapters::JsonAPI | ||
) | ||
} | ||
let(:collection_hash) { collection_serializer.to_hash } | ||
|
||
context 'top level' do | ||
subject(:users){ collection_hash.fetch(:users) } | ||
its(:size) { should eq(2) } | ||
|
||
it 'contains the correct first user properties' do | ||
expect(users[0]).to include( | ||
:id => user.id, | ||
:name => user.name, | ||
:age => user.age, | ||
:controller_name => 'some_controller', | ||
:message_from_above => nil | ||
) | ||
end | ||
|
||
it 'contains the correct second user properties' do | ||
expect(users[1]).to include( | ||
:id => friend.id, | ||
:name => friend.name, | ||
:age => friend.age, | ||
:controller_name => 'some_controller', | ||
:message_from_above => nil | ||
) | ||
end | ||
|
||
it 'contains the correct user links' do | ||
expect(users.first.fetch(:links)).to include( | ||
:self => "http://foo.bar.com/#{user.id}", | ||
# these links are added by embedding entities | ||
:manager => manager.id, | ||
:friends => [friend.id] | ||
) | ||
end | ||
|
||
context 'sub entity' do | ||
subject(:linked_managers){ collection_hash.fetch(:linked).fetch(:managers) } | ||
its(:size) { should eq(1) } | ||
|
||
it "contains the correct properties and links" do | ||
expect(linked_managers.first).to include( | ||
:id => manager.id, | ||
:name => manager.name, | ||
:age => manager.age, | ||
:links => { :self => "http://foo.bar.com/#{manager.id}" } | ||
) | ||
end | ||
end | ||
end | ||
|
||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to
Adapter#initalize
data[:resource_collection]
will be a hash the first time it is accessed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. And that's my own code :)