jei 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/jei.rb CHANGED
@@ -1,14 +1,7 @@
1
1
  require 'json'
2
2
  require 'set'
3
3
 
4
- require 'jei/builders/attributes_node_builder'
5
- require 'jei/builders/data_node_builder'
6
- require 'jei/builders/document_builder'
7
- require 'jei/builders/included_node_builder'
8
- require 'jei/builders/links_node_builder'
9
- require 'jei/builders/relationship_node_builder'
10
- require 'jei/builders/relationships_node_builder'
11
- require 'jei/builders/resource_node_builder'
4
+ require 'jei/error'
12
5
 
13
6
  require 'jei/nodes/node'
14
7
 
@@ -28,14 +21,23 @@ require 'jei/nodes/resource_node'
28
21
  require 'jei/nodes/data_node'
29
22
  require 'jei/nodes/collection_data_node'
30
23
 
31
- require 'jei/attribute'
24
+ require 'jei/builders/attributes_node_builder'
25
+ require 'jei/builders/data_node_builder'
26
+ require 'jei/builders/document_builder'
27
+ require 'jei/builders/included_node_builder'
28
+ require 'jei/builders/links_node_builder'
29
+ require 'jei/builders/relationship_node_builder'
30
+ require 'jei/builders/relationships_node_builder'
31
+ require 'jei/builders/resource_node_builder'
32
+
32
33
  require 'jei/document'
34
+ require 'jei/fieldset'
33
35
  require 'jei/link'
34
36
  require 'jei/path'
35
- require 'jei/relationship'
36
37
  require 'jei/serializer'
37
38
 
38
- require 'jei/version'
39
+ require 'jei/field'
40
+ require 'jei/attribute'
41
+ require 'jei/relationship'
39
42
 
40
- module Jei
41
- end
43
+ require 'jei/version'
data/lib/jei/attribute.rb CHANGED
@@ -1,22 +1,4 @@
1
1
  module Jei
2
- class Attribute
3
- # @return [Symbol]
4
- attr_reader :name
5
-
6
- # @param [Symbol] name
7
- # @param [Proc, Symbol] value
8
- def initialize(name, value = name)
9
- @name = name
10
- @value = value
11
- end
12
-
13
- # @param [Serializer] serializer
14
- def evaluate(serializer)
15
- if @value.is_a?(Proc)
16
- serializer.instance_eval(&@value)
17
- else
18
- serializer.resource.send(@value)
19
- end
20
- end
2
+ class Attribute < Field
21
3
  end
22
4
  end
@@ -1,12 +1,14 @@
1
1
  module Jei
2
- module Builder
2
+ module Builders
3
3
  module AttributesNodeBuilder
4
+ include Nodes
5
+
4
6
  # @param [Serializer] serializer
5
7
  # @return [AttributesNode]
6
- def self.build(serializer)
8
+ def self.build(attributes, serializer)
7
9
  node = AttributesNode.new
8
10
 
9
- serializer.attributes.values.each do |attribute|
11
+ attributes.each do |attribute|
10
12
  node.children << AttributeNode.new(serializer, attribute)
11
13
  end
12
14
 
@@ -1,6 +1,8 @@
1
1
  module Jei
2
- module Builder
2
+ module Builders
3
3
  module DataNodeBuilder
4
+ include Nodes
5
+
4
6
  # @param [Serializer] serializer
5
7
  # @return [DataNode]
6
8
  def self.build(serializer)
@@ -1,6 +1,8 @@
1
1
  module Jei
2
- module Builder
2
+ module Builders
3
3
  module DocumentBuilder
4
+ include Nodes
5
+
4
6
  # @param [Object] resource
5
7
  # @param [Hash<Symbol, Object>] options
6
8
  # @return [Document]
@@ -17,57 +19,48 @@ module Jei
17
19
  return document
18
20
  end
19
21
 
22
+ fieldsets = options[:fields] ? Fieldset.parse(options[:fields]) : {}
23
+
20
24
  if resource.is_a?(Enumerable)
21
25
  node = CollectionDataNode.new
22
26
 
23
27
  if options[:include]
24
28
  paths = Path.parse(options[:include])
25
- included_resources = Set.new
29
+ serializers = Set.new
26
30
 
27
31
  resource.each do |r|
28
- Path.find(paths, r, included_resources)
29
-
30
- serializer =
31
- if options[:serializer]
32
- options[:serializer].new(r)
33
- else
34
- Serializer.factory(r)
35
- end
36
-
37
- node.children << ResourceNodeBuilder.build(serializer)
32
+ serializer = Serializer.factory(r, options[:serializer])
33
+ Path.find(paths, serializer, serializers)
34
+ fieldset = fieldsets[serializer.type]
35
+ node.children << ResourceNodeBuilder.build(serializer, fieldset)
38
36
  end
39
37
 
40
- root.children << IncludedNode.build(included_resources)
38
+ root.children << IncludedNodeBuilder.build(serializers, fieldsets)
41
39
  else
42
40
  resource.each do |r|
43
- serializer =
44
- if options[:serializer]
45
- options[:serializer].new(r)
46
- else
47
- Serializer.factory(r)
48
- end
49
-
50
- node.children << ResourceNodeBuilder.build(serializer)
41
+ serializer = Serializer.factory(r, options[:serializer])
42
+ fieldset = fieldsets[serializer.type]
43
+ node.children << ResourceNodeBuilder.build(serializer, fieldset)
51
44
  end
52
45
  end
53
46
 
54
47
  root.children << node
55
48
  else
56
- serializer =
57
- if options[:serializer]
58
- options[:serializer].new(resource)
59
- else
60
- Serializer.factory(resource)
61
- end
49
+ node = DataNode.new
50
+
51
+ serializer = Serializer.factory(resource, options[:serializer])
52
+ fieldset = fieldsets[serializer.type]
62
53
 
63
- root.children << DataNodeBuilder.build(serializer)
54
+ node.children << ResourceNodeBuilder.build(serializer, fieldset)
64
55
 
65
56
  if options[:include]
66
57
  paths = Path.parse(options[:include])
67
- included_resources = Set.new
68
- Path.find(paths, resource, included_resources)
69
- root.children << IncludedNodeBuilder.build(included_resources)
58
+ serializers = Set.new
59
+ Path.find(paths, serializer, serializers)
60
+ root.children << IncludedNodeBuilder.build(serializers, fieldsets)
70
61
  end
62
+
63
+ root.children << node
71
64
  end
72
65
 
73
66
  document
@@ -1,14 +1,17 @@
1
1
  module Jei
2
- module Builder
2
+ module Builders
3
3
  module IncludedNodeBuilder
4
- # @param [Set<Object>] resources
4
+ include Nodes
5
+
6
+ # @param [Set<Serializer>] serializers
7
+ # @param [Hash<String, String>] fieldset
5
8
  # @return [IncludedNode]
6
- def self.build(resources)
9
+ def self.build(serializers, fieldsets = {})
7
10
  node = IncludedNode.new
8
11
 
9
- resources.each do |resource|
10
- serializer = Serializer.factory(resource)
11
- node.children << ResourceNodeBuilder.build(serializer)
12
+ serializers.each do |serializer|
13
+ fieldset = fieldsets[serializer.type]
14
+ node.children << ResourceNodeBuilder.build(serializer, fieldset)
12
15
  end
13
16
 
14
17
  node
@@ -1,6 +1,8 @@
1
1
  module Jei
2
- module Builder
2
+ module Builders
3
3
  module LinksNodeBuilder
4
+ include Nodes
5
+
4
6
  # @param [Array<Link>] links
5
7
  # @return [LinksNode]
6
8
  def self.build(links)
@@ -1,13 +1,15 @@
1
1
  module Jei
2
- module Builder
2
+ module Builders
3
3
  module RelationshipNodeBuilder
4
+ include Nodes
5
+
4
6
  # @param [Relationship] relationship
5
7
  # @param [Serializer] serializer
6
8
  # @return [RelationshipNode]
7
9
  def self.build(relationship, serializer)
8
10
  node = RelationshipNode.new(relationship)
9
11
 
10
- if !relationship.options[:no_data]
12
+ if relationship.options[:data]
11
13
  node.children <<
12
14
  case relationship
13
15
  when BelongsToRelationship
@@ -33,7 +35,7 @@ module Jei
33
35
  node = DataNode.new
34
36
  resource = relationship.evaluate(serializer)
35
37
 
36
- serializer = Serializer.factory(resource)
38
+ serializer = Serializer.factory(resource, relationship.options[:serializer])
37
39
  node.children << ResourceIdentifierNode.new(serializer)
38
40
 
39
41
  node
@@ -47,7 +49,7 @@ module Jei
47
49
  resources = relationship.evaluate(serializer)
48
50
 
49
51
  resources.each do |resource|
50
- serializer = Serializer.factory(resource)
52
+ serializer = Serializer.factory(resource, relationship.options[:serializer])
51
53
  node.children << ResourceIdentifierNode.new(serializer)
52
54
  end
53
55
 
@@ -1,12 +1,14 @@
1
1
  module Jei
2
- module Builder
2
+ module Builders
3
3
  module RelationshipsNodeBuilder
4
+ include Nodes
5
+
4
6
  # @param [Serializer] serializer
5
7
  # @return [RelationshipsNode]
6
- def self.build(serializer)
8
+ def self.build(relationships, serializer)
7
9
  node = RelationshipsNode.new
8
10
 
9
- serializer.relationships.values.each do |relationship|
11
+ relationships.each do |relationship|
10
12
  node.children << RelationshipNodeBuilder.build(relationship, serializer)
11
13
  end
12
14
 
@@ -1,19 +1,26 @@
1
1
  module Jei
2
- module Builder
2
+ module Builders
3
3
  module ResourceNodeBuilder
4
+ include Nodes
5
+
4
6
  # @param [Serializer] serializer
7
+ # @param [Array<Symbol>] fieldset
5
8
  # @return [ResourceNode]
6
- def self.build(serializer)
9
+ def self.build(serializer, fieldset = nil)
7
10
  node = ResourceNode.new
8
11
 
9
12
  node.children << ResourceIdentifierNode.new(serializer)
10
13
 
11
- if serializer.attributes.any?
12
- node.children << AttributesNodeBuilder.build(serializer)
14
+ attributes = serializer.attributes(fieldset).values
15
+
16
+ if attributes.any?
17
+ node.children << AttributesNodeBuilder.build(attributes, serializer)
13
18
  end
14
19
 
15
- if serializer.relationships.any?
16
- node.children << RelationshipsNodeBuilder.build(serializer)
20
+ relationships = serializer.relationships(fieldset).values
21
+
22
+ if relationships.any?
23
+ node.children << RelationshipsNodeBuilder.build(relationships, serializer)
17
24
  end
18
25
 
19
26
  links = serializer.links
data/lib/jei/document.rb CHANGED
@@ -6,23 +6,27 @@ module Jei
6
6
  # @return [DocumentNode]
7
7
  attr_reader :root
8
8
 
9
+ # Builds a document from a resource.
10
+ #
9
11
  # @param [Object] resource
10
12
  # @param [Hash<Symbol, Object>] options
11
- # @option options [Boolean] :jsonapi Add the top level JSON API object to
12
- # the document.
13
- # @option options [Array<Link>] :links Add links related to the primary
14
- # data.
15
- # @option options [Hash<Symbol, Object>] :meta Add top level meta
16
- # information to the document.
17
- # @option options [Class] :serializer Override the default serializer. For
18
- # collections, this works only if all the resources are of the same type.
13
+ # @option options [Hash<String, String>] :fields restrict resource
14
+ # attributes and relationships to a user-defined set of fields
15
+ # @option options [String] :include a list of relationship paths
16
+ # @option options [Boolean] :jsonapi add the top level JSON API object to
17
+ # the document
18
+ # @option options [Array<Link>] :links add links related to the primary
19
+ # data
20
+ # @option options [Hash<Symbol, Object>] :meta add top level meta
21
+ # information to the document
22
+ # @option options [Class] :serializer override the default serializer
19
23
  # @return [Document]
20
24
  def self.build(resource, options = {})
21
- Builder::DocumentBuilder.build(resource, options)
25
+ Builders::DocumentBuilder.build(resource, options)
22
26
  end
23
27
 
24
28
  def initialize
25
- @root = DocumentNode.new
29
+ @root = Nodes::DocumentNode.new
26
30
  end
27
31
 
28
32
  # @return [Hash<Symbol, Object>]
data/lib/jei/error.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Jei
2
+ class Error < RuntimeError
3
+ end
4
+ end
data/lib/jei/field.rb ADDED
@@ -0,0 +1,22 @@
1
+ module Jei
2
+ class Field
3
+ # @return [Symbol]
4
+ attr_reader :name
5
+
6
+ # @param [Symbol] name
7
+ # @param [Proc, Symbol] value
8
+ def initialize(name, value = name)
9
+ @name = name
10
+ @value = value
11
+ end
12
+
13
+ # @param [Serializer] serializer
14
+ def evaluate(serializer)
15
+ if @value.is_a?(Proc)
16
+ serializer.instance_eval(&@value)
17
+ else
18
+ serializer.resource.send(@value)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Jei
2
+ class Fieldset
3
+ NAME_SEPARATOR = ','
4
+
5
+ def self.parse(raw_fields)
6
+ fields = {}
7
+
8
+ raw_fields.each do |type, names|
9
+ fields[type] = names.split(NAME_SEPARATOR).map(&:to_sym)
10
+ end
11
+
12
+ fields
13
+ end
14
+ end
15
+ end
@@ -1,17 +1,19 @@
1
1
  module Jei
2
- # @see http://jsonapi.org/format/1.0/#document-resource-object-attributes
3
- class AttributeNode < Node
4
- # @param [Serializer] serializer
5
- # @param [Attribute] attribute
6
- def initialize(serializer, attribute)
7
- super()
8
- @serializer = serializer
9
- @attribute = attribute
10
- end
2
+ module Nodes
3
+ # @see http://jsonapi.org/format/1.0/#document-resource-object-attributes
4
+ class AttributeNode < Node
5
+ # @param [Serializer] serializer
6
+ # @param [Attribute] attribute
7
+ def initialize(serializer, attribute)
8
+ super()
9
+ @serializer = serializer
10
+ @attribute = attribute
11
+ end
11
12
 
12
- # @param [Hash<Symbol, Object>] context
13
- def visit(context)
14
- context[@attribute.name] = @attribute.evaluate(@serializer)
13
+ # @param [Hash<Symbol, Object>] context
14
+ def visit(context)
15
+ context[@attribute.name] = @attribute.evaluate(@serializer)
16
+ end
15
17
  end
16
18
  end
17
19
  end
@@ -1,11 +1,13 @@
1
1
  module Jei
2
- # @see http://jsonapi.org/format/1.0/#document-resource-object-attributes
3
- class AttributesNode < Node
4
- # @param [Hash<Symbol, Object>] context
5
- def visit(context)
6
- attributes = {}
7
- children.each { |child| child.visit(attributes) }
8
- context[:attributes] = attributes
2
+ module Nodes
3
+ # @see http://jsonapi.org/format/1.0/#document-resource-object-attributes
4
+ class AttributesNode < Node
5
+ # @param [Hash<Symbol, Object>] context
6
+ def visit(context)
7
+ attributes = {}
8
+ children.each { |child| child.visit(attributes) }
9
+ context[:attributes] = attributes
10
+ end
9
11
  end
10
12
  end
11
13
  end