Skip to content

Commit

Permalink
add relationship level links and meta options
Browse files Browse the repository at this point in the history
  • Loading branch information
tchak committed Oct 20, 2015
1 parent b2cd7bb commit 31cfd12
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 1 deletion.
34 changes: 33 additions & 1 deletion lib/active_model/serializer/adapter/json_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,41 @@ def relationship_value_for(serializer, options = {})
end
end

def relationship_links_for(name, owner, options = {})
options[:links].each_with_object({}) do |(key, link), hash|
if link.is_a? Proc
hash[key] = link.call(owner, name)
else
hash[key] = link
end

hash
end
end

def relationship_meta_for(name, owner, options = {})
if options[:meta].is_a? Proc
options[:meta].call(owner, name)
else
options[:meta]
end
end

def relationships_for(serializer)
serializer.associations.each_with_object({}) do |association, hash|
hash[association.key] = { data: relationship_value_for(association.serializer, association.options) }
hash[association.key] = {}

if association.options.fetch(:data, true)
hash[association.key][:data] = relationship_value_for(association.serializer, association.options)
end

if association.options.fetch(:links, false)
hash[association.key][:links] = relationship_links_for(association.name, serializer.object, association.options)
end

if association.options.fetch(:meta, false)
hash[association.key][:meta] = relationship_meta_for(association.name, serializer.object, association.options)
end
end
end

Expand Down
74 changes: 74 additions & 0 deletions test/adapter/json_api/has_many_links_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require 'test_helper'

module ActionController
module Serialization
class JsonApiHasManyLinksTest < ActionController::TestCase
LinkTagSerializer = Class.new(ActiveModel::Serializer) do
has_many :posts, links: { related: -> (object, name) { "http://test.host/tags/#{object.id}/#{name}" } }, data: false
end

class MyController < ActionController::Base
def render_resource_with_has_many_association
@tag = Tag.new(id: 1)
@tag.posts = []
render json: @tag, adapter: :json_api, serializer: LinkTagSerializer
end
end

tests MyController

def test_render_resource_with_has_many_association
get :render_resource_with_has_many_association
expected = {
data: {
id: '1',
type: 'tags',
relationships: {
posts: {
links: {
related: 'http://test.host/tags/1/posts'
}
}
}
}
}
assert_equal expected.to_json, response.body
end
end

class JsonApiHasManyLinksWithDataTest < ActionController::TestCase
LinkTagSerializer = Class.new(ActiveModel::Serializer) do
has_many :posts, links: { related: -> (object, name) { "http://test.host/tags/#{object.id}/#{name}" } }
end

class MyController < ActionController::Base
def render_resource_with_has_many_association
@tag = Tag.new(id: 1)
@tag.posts = []
render json: @tag, adapter: :json_api, serializer: LinkTagSerializer
end
end

tests MyController

def test_render_resource_with_has_many_association
get :render_resource_with_has_many_association
expected = {
data: {
id: '1',
type: 'tags',
relationships: {
posts: {
data: [],
links: {
related: 'http://test.host/tags/1/posts'
}
}
}
}
}
assert_equal expected.to_json, response.body
end
end
end
end
40 changes: 40 additions & 0 deletions test/adapter/json_api/has_many_meta_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'test_helper'

module ActionController
module Serialization
class JsonApiHasManyMetaTest < ActionController::TestCase
MetaTagSerializer = Class.new(ActiveModel::Serializer) do
has_many :posts, meta: -> (_object, _name) { { page: '1' } }
end

class MyController < ActionController::Base
def render_resource_with_has_many_association
@tag = Tag.new(id: 1)
@tag.posts = []
render json: @tag, adapter: :json_api, serializer: MetaTagSerializer
end
end

tests MyController

def test_render_resource_with_has_many_association
get :render_resource_with_has_many_association
expected = {
data: {
id: '1',
type: 'tags',
relationships: {
posts: {
data: [],
meta: {
page: '1'
}
}
}
}
}
assert_equal expected.to_json, response.body
end
end
end
end
74 changes: 74 additions & 0 deletions test/adapter/json_api/has_one_links_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require 'test_helper'

module ActionController
module Serialization
class JsonApiHasOneLinksTest < ActionController::TestCase
LinkTagSerializer = Class.new(ActiveModel::Serializer) do
has_one :post, links: { related: -> (object, name) { "http://test.host/tags/#{object.id}/#{name}" } }, data: false
end

class MyController < ActionController::Base
def render_resource_with_has_one_association
@tag = Tag.new(id: 1)
@tag.post = Post.new(id: 1)
render json: @tag, adapter: :json_api, serializer: LinkTagSerializer
end
end

tests MyController

def test_render_resource_with_has_one_association
get :render_resource_with_has_one_association
expected = {
data: {
id: '1',
type: 'tags',
relationships: {
post: {
links: {
related: 'http://test.host/tags/1/post'
}
}
}
}
}
assert_equal expected.to_json, response.body
end
end

class JsonApiHasOneLinksWithDataTest < ActionController::TestCase
LinkTagSerializer = Class.new(ActiveModel::Serializer) do
has_one :post, links: { related: -> (object, name) { "http://test.host/tags/#{object.id}/#{name}" } }
end

class MyController < ActionController::Base
def render_resource_with_has_one_association
@tag = Tag.new(id: 1)
@tag.post = Post.new(id: 1)
render json: @tag, adapter: :json_api, serializer: LinkTagSerializer
end
end

tests MyController

def test_render_resource_with_has_one_association
get :render_resource_with_has_one_association
expected = {
data: {
id: '1',
type: 'tags',
relationships: {
post: {
data: { id: '1', type: 'posts' },
links: {
related: 'http://test.host/tags/1/post'
}
}
}
}
}
assert_equal expected.to_json, response.body
end
end
end
end
40 changes: 40 additions & 0 deletions test/adapter/json_api/has_one_meta_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'test_helper'

module ActionController
module Serialization
class JsonApiHasOneMetaTest < ActionController::TestCase
MetaTagSerializer = Class.new(ActiveModel::Serializer) do
has_one :post, meta: -> (_object, _name) { { deleted: true } }
end

class MyController < ActionController::Base
def render_resource_with_has_one_association
@tag = Tag.new(id: 1)
@tag.post = Post.new(id: 1)
render json: @tag, adapter: :json_api, serializer: MetaTagSerializer
end
end

tests MyController

def test_render_resource_with_has_one_association
get :render_resource_with_has_one_association
expected = {
data: {
id: '1',
type: 'tags',
relationships: {
post: {
data: { id: '1', type: 'posts' },
meta: {
deleted: true
}
}
}
}
}
assert_equal expected.to_json, response.body
end
end
end
end

0 comments on commit 31cfd12

Please sign in to comment.