jacoat 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b90bcea2b15f17d4e2766df1d3a8c18c50de275f
4
- data.tar.gz: 4e11452c19ca00e9f38edbb110f6cb52d8f74073
3
+ metadata.gz: 396c87751d11cb60f85a7c3c671fe33043989aed
4
+ data.tar.gz: abae97ede6d6d52177f26a381ecac86f8877fdac
5
5
  SHA512:
6
- metadata.gz: c0b4091682a4daaedf3c1eabf199e1a731ff78728283a26db4acdba7904f21955139f84602e7ace4af2d6d6b9da4b37cfc410be7b5f4d081a7263915cc44ed8f
7
- data.tar.gz: 9fb97a37ba63348520f9157702f94b4e0fe6c214f3e41e5fd1adbaeb7b5119d203c92f9b857dc672b6914352e2fec96ca7083b8f32fa5e87171d61474efe75b5
6
+ metadata.gz: 25bedd6912572567f7ac48970f8fc4c47f11418a7fb533dd6aea6eb7cf783ea8bc19c58e985d9711fe84797ef04a08d3b587054d12f3923841d2624363790370
7
+ data.tar.gz: d4158ab50b8ff54d2c227d35e6d2ad87b3b12e3a0aa7ac8c65b0e368b9c4f740f505d9a4e361a7c505bf442abe0a64f8435d33d77e01b5b477d0910266ef52e3
data/jacoat.gemspec CHANGED
@@ -21,5 +21,7 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_development_dependency "bundler", "~> 1.10"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "representable", "~> 2.3"
25
+ spec.add_development_dependency "multi_json", "~> 1.11"
24
26
  spec.add_development_dependency "rspec"
25
27
  end
@@ -11,22 +11,38 @@ require 'jacoat/document/relationship'
11
11
 
12
12
  module Jacoat
13
13
  class Document
14
- attr_reader :data, :errors, :meta, :jsonapi, :links, :included
15
- def initialize(arguments = {})
16
- validate_arguments(arguments)
17
- @has_data = true if arguments.has_key?(:data)
18
- @data = Data.process(arguments[:data]) if arguments.has_key?(:data)
19
- @errors = Error.new(arguments[:errors]) if arguments.has_key?(:errors)
20
- @meta = Meta.new(arguments[:meta]) if arguments.has_key?(:meta)
21
- @jsonapi = Jsonapi.new(arguments[:jsonapi]) if arguments.has_key?(:jsonapi)
22
- @links = Link.process(arguments[:links]) if arguments.has_key?(:links)
23
- @included = Included.process(arguments[:included]) if arguments.has_key?(:included)
14
+ attr_reader :data
15
+ attr_accessor :errors, :meta, :jsonapi, :links, :included
16
+
17
+ def self.from_jsonapi(arguments)
18
+ document = Document.new
19
+ document.data = Data.from_jsonapi(arguments[:data]) if arguments.has_key?(:data)
20
+
21
+
22
+ document.errors = Error.from_jsonapi(arguments[:errors]) if arguments.has_key?(:errors)
23
+ document.meta = Meta.from_jsonapi(arguments[:meta]) if arguments.has_key?(:meta)
24
+ document.jsonapi = Jsonapi.from_jsonapi(arguments[:jsonapi]) if arguments.has_key?(:jsonapi)
25
+ document.links = Link.from_jsonapi(arguments[:links]) if arguments.has_key?(:links)
26
+ document.included = Included.from_jsonapi(arguments[:included]) if arguments.has_key?(:included)
27
+ document
24
28
  end
25
-
26
- def validate_arguments(arguments)
27
- raise Invalid.new('included key without data key') if arguments.has_key?(:included) && !arguments.has_key?(:data)
28
- raise Invalid.new('must contain data, errors or meta key') if !arguments.has_key?(:data) && !arguments.has_key?(:errors) && !arguments.has_key?(:meta)
29
- raise Invalid.new('data and errors keys set') if arguments.has_key?(:data) && arguments.has_key?(:errors)
29
+
30
+ def data=(data)
31
+ @has_data = true
32
+ @data = data
33
+ end
34
+
35
+ def valid?
36
+ validate_arguments
37
+ true
38
+ rescue Invalid
39
+ return false
40
+ end
41
+
42
+ def validate_arguments
43
+ raise Invalid.new('included key without data key') if @included && !@data
44
+ raise Invalid.new('must contain data, errors or meta key') if !@data && !@errors && !@meta
45
+ raise Invalid.new('data and errors keys set') if @data && @errors
30
46
  end
31
47
 
32
48
  def to_hash
@@ -1,6 +1,12 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Attributes
4
+ attr_reader :hash
5
+
6
+ def self.from_jsonapi(arguments = {})
7
+ Attributes.new(arguments)
8
+ end
9
+
4
10
  def initialize(arguments = {})
5
11
  @hash = arguments
6
12
  end
@@ -1,7 +1,7 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Data
4
- def self.process(arguments)
4
+ def self.from_jsonapi(arguments)
5
5
  data = Data.new
6
6
  if arguments.is_a?(Array)
7
7
  data.resource = create_resource_array(arguments)
@@ -14,9 +14,9 @@ module Jacoat
14
14
  def self.create_resource(arguments)
15
15
  return nil if arguments.nil?
16
16
  if Detector.what_is(arguments) == "resource"
17
- return Resource.new(arguments)
17
+ return Resource.from_jsonapi(arguments)
18
18
  else
19
- return ResourceIdentifier.new(arguments)
19
+ return ResourceIdentifier.from_jsonapi(arguments)
20
20
  end
21
21
  end
22
22
 
@@ -24,15 +24,18 @@ module Jacoat
24
24
  resources = []
25
25
  arguments.each do |resource|
26
26
  if Detector.what_is(resource) == "resource"
27
- resources << Resource.new(resource)
27
+ resources << Resource.from_jsonapi(resource)
28
28
  else
29
- resources << ResourceIdentifier.new(resource)
29
+ resources << ResourceIdentifier.from_jsonapi(resource)
30
30
  end
31
31
  end
32
32
  resources
33
33
  end
34
34
 
35
- attr_accessor :resource
35
+ attr_accessor :resource
36
+ def resources=(resources)
37
+ @resource = resources
38
+ end
36
39
  def resources
37
40
  @resource
38
41
  end
@@ -1,14 +1,16 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Error
4
- attr_reader :id, :links, :status, :code, :title, :detail, :meta
5
- def initialize(arguments = {})
6
- @id = arguments[:id]
7
- @links = Link.process(arguments[:links]) if arguments.has_key?(:links)
4
+ attr_accessor :id, :links, :status, :code, :title, :detail, :meta
5
+ def self.from_jsonapi(arguments)
6
+ error = Error.new
7
+ error.id = arguments[:id]
8
+ error.links = Link.from_jsonapi(arguments[:links]) if arguments.has_key?(:links)
8
9
  %w{ status code title detail }.each do |type|
9
- self.instance_variable_set("@#{type}", arguments[type.to_sym]) if arguments.has_key?(type.to_sym)
10
+ error.instance_variable_set("@#{type}", arguments[type.to_sym]) if arguments.has_key?(type.to_sym)
10
11
  end
11
- @meta = Meta.new(arguments[:meta]) if arguments.has_key?(:meta)
12
+ error.meta = Meta.from_jsonapi(arguments[:meta]) if arguments.has_key?(:meta)
13
+ error
12
14
  end
13
15
 
14
16
  def to_hash
@@ -1,10 +1,10 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Included
4
- def self.process(arguments)
4
+ def self.from_jsonapi(arguments)
5
5
  resources = []
6
6
  arguments.each do |item|
7
- resources << Resource.new(item)
7
+ resources << Resource.from_jsonapi(item)
8
8
  end
9
9
  included = Included.new
10
10
  included.resources = resources
@@ -1,9 +1,12 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Jsonapi
4
- attr_reader :version
5
- def initialize(arguments = {})
6
- @version = arguments[:version]
4
+ attr_accessor :version
5
+
6
+ def self.from_jsonapi(arguments)
7
+ jsonapi = Jsonapi.new
8
+ jsonapi.version = arguments[:version]
9
+ jsonapi
7
10
  end
8
11
 
9
12
  def to_hash
@@ -1,13 +1,14 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Link
4
- def self.process(hash)
5
- Link.new(hash)
4
+ def self.from_jsonapi(hash)
5
+ link = Link.new
6
+ link.process_links(hash)
7
+ link
6
8
  end
7
9
 
8
- def initialize(arguments = {})
10
+ def initialize
9
11
  @hash = {}
10
- process_links(arguments)
11
12
  end
12
13
 
13
14
  def method_missing(m, *args)
@@ -26,18 +27,28 @@ module Jacoat
26
27
  end
27
28
  hash
28
29
  end
29
-
30
- private
31
- def process_links(arguments)
32
- arguments.each_pair do |k, v|
33
- if v.is_a?(String)
34
- link = Simple.new(v)
35
- else
36
- link = Complex.new(v)
37
- end
38
- send("#{k}=", link)
30
+
31
+ def process_links(arguments)
32
+ return if arguments.nil?
33
+ arguments.each_pair do |k, v|
34
+ if v.is_a?(String)
35
+ link = Simple.new(v)
36
+ else
37
+ link = Complex.new(v)
39
38
  end
39
+ send("#{k}=", link)
40
40
  end
41
+ end
42
+
43
+ def add_link(title, href, options = {})
44
+ if options.empty?
45
+ link = Simple.new(href)
46
+ else
47
+ link = Complex.new(href: href, meta: options)
48
+ end
49
+ send("#{title}=", link)
50
+ self
51
+ end
41
52
 
42
53
  class Simple
43
54
  attr_reader :href
@@ -54,7 +65,7 @@ module Jacoat
54
65
  attr_reader :href, :meta
55
66
  def initialize(arguments)
56
67
  @href = arguments[:href]
57
- @meta = Meta.new(arguments[:meta])
68
+ @meta = Meta.from_jsonapi(arguments[:meta])
58
69
  end
59
70
 
60
71
  def to_hash
@@ -1,9 +1,14 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Meta
4
+ def self.from_jsonapi(arguments)
5
+ meta = Meta.new
6
+ meta.process_meta(arguments)
7
+ meta
8
+ end
9
+
4
10
  def initialize(arguments = {})
5
11
  @hash = {}
6
- process_meta(arguments)
7
12
  end
8
13
 
9
14
  def method_missing(m, *args)
@@ -19,12 +24,11 @@ module Jacoat
19
24
  @hash
20
25
  end
21
26
 
22
- private
23
- def process_meta(arguments)
24
- arguments.each_pair do |k, v|
25
- send("#{k}=", v)
26
- end
27
+ def process_meta(arguments)
28
+ arguments.each_pair do |k, v|
29
+ send("#{k}=", v)
27
30
  end
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -1,19 +1,19 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Relationship
4
- attr_reader :id, :type, :data, :links
5
- def self.process(hash)
4
+ attr_accessor :id, :type, :data, :links
5
+ def self.from_jsonapi(hash)
6
6
  relationships = []
7
7
  hash.each_pair do |k, v|
8
- relationships << Document::Relationship.new(k, v)
8
+ relationship = Document::Relationship.new(k)
9
+ relationship.process_jsonapi(v)
10
+ relationships << relationship
9
11
  end
10
12
  relationships
11
13
  end
12
14
 
13
- def initialize(type, body)
15
+ def initialize(type)
14
16
  @type = type.to_s
15
- process_data(body[:data]) if body.has_key?(:data)
16
- process_body(body[:links]) if body.has_key?(:links)
17
17
  end
18
18
 
19
19
  def to_hash
@@ -24,13 +24,19 @@ module Jacoat
24
24
  hash
25
25
  end
26
26
 
27
+ def process_jsonapi(hash)
28
+ process_data(hash[:data]) if hash.has_key?(:data)
29
+ process_body(hash[:links]) if hash.has_key?(:links)
30
+ self
31
+ end
32
+
27
33
  private
28
34
  def process_data(data)
29
- @data = Document::ResourceIdentifier.process(data)
35
+ @data = Document::ResourceIdentifier.from_jsonapi(data)
30
36
  end
31
37
 
32
38
  def process_body(links)
33
- @links = Document::Link.process(links)
39
+ @links = Document::Link.from_jsonapi(links)
34
40
  end
35
41
 
36
42
  def data_to_hash
@@ -1,19 +1,25 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class Resource
4
- attr_reader :id, :type, :attributes, :links, :relationships
5
- def initialize(arguments)
6
- @id = arguments[:id]
7
- @type = arguments[:type]
8
- @attributes = Document::Attributes.new(arguments[:attributes])
9
- create_relationships(arguments[:relationships]) if arguments.has_key?(:relationships)
10
- @links = Link.process(arguments[:links]) if arguments.has_key?(:links)
4
+ attr_accessor :id, :type, :attributes, :links, :relationships
5
+
6
+ def self.from_jsonapi(arguments)
7
+ resource = Resource.new(arguments[:id], arguments[:type])
8
+ resource.attributes = Document::Attributes.from_jsonapi(arguments[:attributes])
9
+ resource.create_relationships(arguments[:relationships]) if arguments.has_key?(:relationships)
10
+ resource.links = Link.from_jsonapi(arguments[:links]) if arguments.has_key?(:links)
11
+ resource
12
+ end
13
+
14
+ def initialize(id, type)
15
+ @id = id
16
+ @type = type
11
17
  end
12
18
 
13
19
  def create_relationships(hash)
14
20
  @relationships = []
15
21
  hash.each_pair do |k, v|
16
- @relationships << Document::Relationship.new(k, v)
22
+ @relationships << Document::Relationship.new(k).process_jsonapi(v)
17
23
  end
18
24
  end
19
25
 
@@ -1,29 +1,33 @@
1
1
  module Jacoat
2
2
  class Document
3
3
  class ResourceIdentifier
4
- attr_reader :id, :type, :relationships
5
- def self.process(body)
4
+ attr_accessor :id, :type, :relationships
5
+ def self.from_jsonapi(body)
6
6
  if body.is_a?(Array)
7
7
  resources = []
8
8
  body.each do |item|
9
- resources << ResourceIdentifier.new(item)
9
+ resources << ResourceIdentifier.new(item[:id], item[:type]).process_jsonapi(item)
10
10
  end
11
11
  else
12
- resources = ResourceIdentifier.new(body)
12
+ resources = ResourceIdentifier.new(body[:id], body[:type]).process_jsonapi(body)
13
13
  end
14
14
  resources
15
15
  end
16
16
 
17
- def initialize(arguments)
18
- @id = arguments[:id]
19
- @type = arguments[:type]
17
+ def initialize(id, type)
18
+ @id = id
19
+ @type = type
20
+ end
21
+
22
+ def process_jsonapi(arguments)
20
23
  create_relationships(arguments[:relationships]) if arguments.has_key?(:relationships)
24
+ self
21
25
  end
22
26
 
23
27
  def create_relationships(hash)
24
28
  @relationships = []
25
29
  hash.each_pair do |k, v|
26
- @relationships << Document::Relationship.new(k, v)
30
+ @relationships << Document::Relationship.new(k).process_jsonapi(v)
27
31
  end
28
32
  end
29
33
 
@@ -0,0 +1,147 @@
1
+ require 'multi_json'
2
+ require 'representable/json'
3
+ require 'representable/hash_methods'
4
+ require 'jacoat/representable/has_one'
5
+
6
+ module Jacoat
7
+ module Representable
8
+ attr_accessor :type
9
+
10
+ def self.included(base)
11
+ base.class_eval do
12
+ include ::Representable
13
+ include ::Representable::JSON
14
+ extend ClassMethods
15
+ include InstanceMethods
16
+ end
17
+ end
18
+
19
+ module ClassMethods
20
+ def type(type)
21
+ representable_attrs[:_type] = type.to_s
22
+ end
23
+
24
+ def links
25
+ end
26
+
27
+ def link(link, &block)
28
+ representable_attrs[:_link] = {} if representable_attrs[:_link].nil?
29
+ representable_attrs[:_link][link] = block if block_given?
30
+ end
31
+
32
+ def has_one(name, options = {}, &block)
33
+ add_relationship(name, :_has_one, options, block)
34
+ end
35
+
36
+ def has_many(name, options = {}, &block)
37
+ add_relationship(name, :_has_many, options, block)
38
+ end
39
+
40
+ def relationships
41
+ end
42
+
43
+ private
44
+ def add_relationship(object, type, options, block)
45
+ representable_attrs[type] = {} unless representable_attrs.has_key?(type)
46
+ rel = HasOne.new
47
+ rel.options = options
48
+ rel.instance_eval(&block)
49
+ representable_attrs[type][object] = rel
50
+ end
51
+ end
52
+
53
+ module InstanceMethods
54
+ def from_hash(hash, options={})
55
+ hash = from_document(hash)
56
+ super(hash, options.merge(:only_body => true))
57
+ end
58
+
59
+ def to_hash(options={})
60
+ res = super(options.merge(:only_body => true))
61
+ to_document(res, options)
62
+ end
63
+
64
+ private
65
+ def from_document(hash)
66
+ document = Jacoat::Document.from_jsonapi(symbolize_keys(hash))
67
+ attributes = document.data.resource.attributes.hash
68
+ attributes = from_document_set_relationships(hash, attributes)
69
+ stringify_keys(attributes)
70
+ end
71
+
72
+ def from_document_set_relationships(hash, attributes)
73
+ representable_attrs[:_has_one].each_key do |k|
74
+ attributes["#{k}_id"] = hash["data"]["relationships"][k.to_s]["data"]["id"].to_i
75
+ end
76
+ attributes
77
+ end
78
+
79
+ def to_document(hash, options = {})
80
+ document = Jacoat::Document.new
81
+ document.data = generate_resource(hash)
82
+ document.data.relationships = relationship_array(hash)
83
+ document.links = generate_links(hash)
84
+ document.to_hash
85
+ end
86
+
87
+ def generate_links(hash)
88
+ lk = Jacoat::Document::Link.new
89
+ @representable_attrs[:_link].each_pair do |link, block|
90
+ href = represented.instance_eval(&@representable_attrs[:_link][link.to_sym])
91
+ lk.add_link(link.to_s, href)
92
+ end
93
+ lk
94
+ end
95
+
96
+ def generate_resource(hash)
97
+ id = hash.delete("id")
98
+ res = Jacoat::Document::Resource.new(id, representable_attrs[:_type])
99
+ res.attributes = Jacoat::Document::Attributes.new(hash)
100
+ res
101
+ end
102
+
103
+ def relationship_array(hash)
104
+ relationships = []
105
+ @representable_attrs[:_has_one].each_pair do |item, object|
106
+ rel = Jacoat::Document::Relationship.new(item.to_s)
107
+ object.links.each_pair do |k, block|
108
+ href = represented.instance_eval(&block)
109
+ rel.links = Jacoat::Document::Link.new.add_link(k.to_s, href)
110
+ end
111
+ relationships.push(rel)
112
+ end
113
+ relationships
114
+ end
115
+
116
+ def symbolize_keys(hash)
117
+ hash.inject({}){|result, (key, value)|
118
+ new_key = case key
119
+ when String then key.to_sym
120
+ else key
121
+ end
122
+ new_value = case value
123
+ when Hash then symbolize_keys(value)
124
+ else value
125
+ end
126
+ result[new_key] = new_value
127
+ result
128
+ }
129
+ end
130
+
131
+ def stringify_keys(hash)
132
+ hash.inject({}){|result, (key, value)|
133
+ new_key = case key
134
+ when Symbol then key.to_s
135
+ else key
136
+ end
137
+ new_value = case value
138
+ when Hash then symbolize_keys(value)
139
+ else value
140
+ end
141
+ result[new_key] = new_value
142
+ result
143
+ }
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,12 @@
1
+ module Jacoat
2
+ module Representable
3
+ class HasOne
4
+ attr_accessor :links, :options
5
+
6
+ def link(link, &block)
7
+ @links = {} if @links.nil?
8
+ @links[link] = block
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module Jacoat
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jacoat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Celso Fernandes
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-14 00:00:00.000000000 Z
11
+ date: 2015-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: representable
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: multi_json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.11'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: rspec
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -83,6 +111,8 @@ files:
83
111
  - lib/jacoat/document/relationship.rb
84
112
  - lib/jacoat/document/resource.rb
85
113
  - lib/jacoat/document/resource_identifier.rb
114
+ - lib/jacoat/representable.rb
115
+ - lib/jacoat/representable/has_one.rb
86
116
  - lib/jacoat/version.rb
87
117
  homepage: http://github.com/fernandes/jacoat
88
118
  licenses:
@@ -104,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
134
  version: '0'
105
135
  requirements: []
106
136
  rubyforge_project:
107
- rubygems_version: 2.4.8
137
+ rubygems_version: 2.4.5.1
108
138
  signing_key:
109
139
  specification_version: 4
110
140
  summary: Your JSON-API Coat in Ruby