Skip to content

Commit

Permalink
Add support for resource-level JSON API links.
Browse files Browse the repository at this point in the history
  • Loading branch information
beauby committed Oct 7, 2015
1 parent d02cd30 commit e1274b2
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
14 changes: 13 additions & 1 deletion lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ def self.type(type)
self._type = type
end

def self.links(&block)
self._links_block = block
end

def self.attributes(*attrs)
attrs = attrs.first if attrs.first.class == Array

Expand Down Expand Up @@ -121,8 +125,9 @@ def self.get_serializer_for(klass)
end
end

attr_accessor :object, :root, :scope
attr_accessor :object, :root, :scope, :links
class_attribute :_type, instance_writer: false
class_attribute :_links_block, instance_writer: false

def initialize(object, options = {})
self.object = object
Expand All @@ -136,6 +141,13 @@ def initialize(object, options = {})
define_method scope_name, lambda { scope }
end
end

instance_eval(&_links_block) if _links_block
end

def link(name, value)
self.links ||= {}
self.links[name] = value
end

def json_key
Expand Down
23 changes: 19 additions & 4 deletions lib/active_model/serializer/adapter/json_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def serializable_hash_for_collection(options)

if serializer.paginated?
hash[:links] ||= {}
hash[:links].update(links_for(serializer, options))
hash[:links].update(pagination_links_for(serializer, options))
end

hash
Expand Down Expand Up @@ -134,13 +134,24 @@ def resource_identifier_for(serializer)
{ id: id.to_s, type: type }
end

def attributes_for(serializer, fields)
attributes = serializer.attributes.except(:id)
attributes.slice!(*fields) if fields

attributes
end

def resource_object_for(serializer)
cache_check(serializer) do
resource_object = resource_identifier_for(serializer)

requested_fields = fieldset && fieldset.fields_for(resource_object[:type])
attributes = serializer.attributes.except(:id)
attributes.slice!(*requested_fields) if requested_fields
attributes = attributes_for(serializer, requested_fields)
resource_object[:attributes] = attributes if attributes.any?

links = links_for(serializer)
resource_object[:links] = links if links.any?

resource_object
end
end
Expand Down Expand Up @@ -200,7 +211,11 @@ def add_included_resources_for(serializer, include_tree, included)
end
end

def links_for(serializer, options)
def links_for(serializer)
serializer.links || {}
end

def pagination_links_for(serializer, options)
JsonApi::PaginationLinks.new(serializer.object, options[:context]).serializable_hash(options)
end
end
Expand Down
37 changes: 37 additions & 0 deletions test/adapter/json_api/links_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'test_helper'

LinkPost = Class.new(Model)
class LinkPostSerializer < ActiveModel::Serializer
belongs_to :link_author
end

LinkAuthor = Class.new(Model)
class LinkAuthorSerializer < ActiveModel::Serializer
links do
link :self, href: "//example.com/link_author/#{object.id}"
end
end

module ActiveModel
class Serializer
module Adapter
class JsonApi
class LinksTest < Minitest::Test
def setup
@author = LinkAuthor.new(id: 1337)
end

def test_resource_links
hash = serializable(@author, adapter: :json_api).serializable_hash
expected = {
self: {
href: '//example.com/link_author/1337'
}
}
assert_equal(expected, hash[:data][:links])
end
end
end
end
end
end

0 comments on commit e1274b2

Please sign in to comment.