jsonapi-serializable 0.1.1.beta1 → 0.1.1.beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 366782323070f412105463eeffabe870128e49c6
4
- data.tar.gz: d80674ddfaa130ea341f286c3f12c87ef5e75016
3
+ metadata.gz: 9d7beafa6258df4dd44fa02cc22d7a62b8f0e2d0
4
+ data.tar.gz: fa7223c5647bd81486ec1066e13345a96311081a
5
5
  SHA512:
6
- metadata.gz: 1bb696480c7e20a3dbe1b4d1525301bb0203b7fbe444268a7fd96bb8d684cdc8bddf8e9ed74161b261375f88e1962f8d1f7363647a544f7b040a9aa73aafdd2f
7
- data.tar.gz: 9d17c652fc934460c7d1ef1249d1c32336671ce3fd26ade2acb0d430c98b24f40b56086d719ac481e77a6b6744f1225071564c5101f74b72b2e65b47d3f42160
6
+ metadata.gz: e041bc9ebe1a08d945eb721baf612d70166de3cda15a310de8ba860d3f9bb7cd0dc72c2b40a6bf682c7568a0635bf796ed9ebf3676edd47d93ce4c01fcd96e3c
7
+ data.tar.gz: fd83b712198356d829a7db4b10e2a831d8843a151cfaab7c3a573985a9f8005b2a78f113e0dfbf0b520ca443b18f4194f9635616a8229edf28da847bbbe737a6
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # jsonapi-serializable
2
- Ruby gem for building and rendering [JSON API](http://jsonapi.org) resources.
3
- Built upon the [jsonapi-renderer](https://github.com/beauby/jsonapi) gem.
2
+ Ruby gem for building [JSON API](http://jsonapi.org) resources to be rendered by
3
+ the [jsonapi-renderer](https://github.com/beauby/jsonapi) gem.
4
+
5
+ ## Status
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/jsonapi-serializable.svg)](https://badge.fury.io/rb/jsonapi-serializable)
8
+ [![Build Status](https://secure.travis-ci.org/beauby/jsonapi-serializable.svg?branch=master)](http://travis-ci.org/beauby/jsonapi-serializable?branch=master)
4
9
 
5
10
  ## Installation
6
11
  ```ruby
@@ -24,6 +29,58 @@ require 'jsonapi/serializable'
24
29
  ```
25
30
 
26
31
  Then, define some resource classes:
32
+
33
+ ### For model-based resources
34
+
35
+ For resources that are simple representations of models, the DSL is simplified:
36
+
37
+ ```ruby
38
+ class PostResource < JSONAPI::Serializable::Resource
39
+ type 'posts'
40
+
41
+ id
42
+
43
+ attribute :title
44
+
45
+ attribute :date do
46
+ @model.created_at
47
+ end
48
+
49
+ relationship :author, UserResource do
50
+ link(:self) do
51
+ href @url_helper.link_for_rel('posts', @model.id, 'author')
52
+ meta link_meta: 'some meta'
53
+ end
54
+ link(:related) { @url_helper.link_for_res('users', @model.author.id) }
55
+ meta do
56
+ { relationship_meta: 'some meta' }
57
+ end
58
+ end
59
+
60
+ has_many :comments
61
+
62
+ meta do
63
+ { resource_meta: 'some meta' }
64
+ end
65
+
66
+ link(:self) do
67
+ @url_helper.link_for_res('posts', @model.id)
68
+ end
69
+ end
70
+ ```
71
+ Then, build your resources from your models and render them:
72
+ ```ruby
73
+ # post = some post model
74
+ # UrlHelper is some helper class
75
+ resource = PostResource.new(model: post, url_helper: UrlHelper)
76
+ document = JSONAPI.render(resource)
77
+ ```
78
+
79
+ ### For general resources
80
+
81
+ In case your resource is not a simple representation of one of your models,
82
+ the more general `JSONAPI::Serializable::Resource` class can be used.
83
+
27
84
  ```ruby
28
85
  class PostResource < JSONAPI::Serializable::Resource
29
86
  type 'posts'
@@ -0,0 +1,44 @@
1
+ require 'jsonapi/serializable/model_dsl'
2
+ require 'jsonapi/serializable/resource'
3
+
4
+ module JSONAPI
5
+ module Serializable
6
+ class Model < Resource
7
+ include ModelDSL
8
+
9
+ class << self
10
+ attr_accessor :api_version_val
11
+ end
12
+
13
+ def self.inherited(klass)
14
+ super
15
+ klass.api_version_val = api_version_val
16
+ end
17
+
18
+ id { @model.public_send(:id).to_s }
19
+
20
+ def resource_klass_for(model_klass)
21
+ names = model_klass.name.split('::'.freeze)
22
+ model_klass_name = names.pop
23
+ namespace = names.join('::'.freeze)
24
+ version = self.class.api_version_val
25
+
26
+ klass_name = [namespace, version, "Serializable#{model_klass_name}"]
27
+ .reject(&:nil?)
28
+ .reject(&:empty?)
29
+ .join('::'.freeze)
30
+
31
+ Object.const_get(klass_name)
32
+ end
33
+
34
+ def nil?
35
+ @model.nil?
36
+ end
37
+
38
+ def as_jsonapi(params = {})
39
+ return nil if nil?
40
+ super(params)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,54 @@
1
+ module JSONAPI
2
+ module Serializable
3
+ module ModelDSL
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def api_version(value)
10
+ self.api_version_val = value
11
+ end
12
+
13
+ def type(value = nil)
14
+ value ||= name
15
+ super(value)
16
+ end
17
+
18
+ def attribute(attr, &block)
19
+ block ||= proc { @model.public_send(attr) }
20
+ super(attr, &block)
21
+ end
22
+
23
+ def has_many(rel, resource_klass = nil, &block)
24
+ rel_block = proc do
25
+ if resource_klass
26
+ data do
27
+ @model.public_send(rel).map do |related|
28
+ resource_klass ||= resource_klass_for(related.class)
29
+ resource_klass.new(model: related)
30
+ end
31
+ end
32
+ end
33
+ instance_eval(&block) unless block.nil?
34
+ end
35
+ relationship(rel, &rel_block)
36
+ end
37
+
38
+ def has_one(rel, resource_klass = nil, &block)
39
+ rel_block = proc do
40
+ if resource_klass
41
+ data do
42
+ related = @model.public_send(rel)
43
+ resource_klass ||= resource_klass_for(related.class)
44
+ resource_klass.new(model: related)
45
+ end
46
+ end
47
+ instance_eval(&block) unless block.nil?
48
+ end
49
+ relationship(rel, &rel_block)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -17,8 +17,8 @@ module JSONAPI
17
17
  hash = {}
18
18
  hash[:links] = @_links if @_links.any?
19
19
  hash[:meta] = @_meta unless @_meta.nil?
20
- hash[:data] = eval_linkage_data if included && (@_linkage_data_block ||
21
- @_data_block)
20
+ return hash unless included || (!@_links.any? && @_meta.nil?)
21
+ hash[:data] = eval_linkage_data
22
22
 
23
23
  hash
24
24
  end
@@ -18,51 +18,43 @@ module JSONAPI
18
18
 
19
19
  def self.inherited(klass)
20
20
  super
21
+ klass.type_val = type_val
22
+ klass.type_block = type_block
23
+ klass.id_block = id_block
24
+ klass.meta_val = meta_val
25
+ klass.meta_block = meta_block
21
26
  klass.attribute_blocks = attribute_blocks.dup
22
27
  klass.relationship_blocks = relationship_blocks.dup
23
28
  klass.link_blocks = link_blocks.dup
24
29
  end
25
30
 
26
31
  def initialize(param_hash = {})
32
+ @_param_hash = param_hash
27
33
  param_hash.each { |k, v| instance_variable_set("@#{k}", v) }
28
- @_id = instance_eval(&self.class.id_block)
29
- @_type = self.class.type_val || instance_eval(&self.class.type_block)
30
- @_meta = if self.class.meta_val
31
- self.class.meta_val
32
- elsif self.class.meta_block
33
- instance_eval(&self.class.meta_block)
34
- end
35
- @_attributes = {}
36
- @_relationships = self.class.relationship_blocks
37
- .each_with_object({}) do |(k, v), h|
38
- h[k] = Relationship.new(param_hash, &v)
39
- end
40
- @_links = self.class.link_blocks.each_with_object({}) do |(k, v), h|
41
- h[k] = Link.as_jsonapi(param_hash, &v)
42
- end
43
34
  end
44
35
 
45
36
  def as_jsonapi(params = {})
46
37
  hash = {}
47
- hash[:id] = @_id
48
- hash[:type] = @_type
49
- attr = attributes(params[:fields] || self.class.attribute_blocks.keys)
38
+ hash[:id] = jsonapi_id
39
+ hash[:type] = jsonapi_type
40
+ requested_attrs = params[:fields] || self.class.attribute_blocks.keys
41
+ attr = attributes(requested_attrs)
50
42
  hash[:attributes] = attr if attr.any?
51
- rels = relationships(params[:fields] || @_relationships.keys,
52
- params[:include] || [])
43
+ requested_rels = params[:fields] || self.class.relationship_blocks.keys
44
+ rels = relationships(requested_rels, params[:include] || [])
53
45
  hash[:relationships] = rels if rels.any?
54
- hash[:links] = @_links if @_links.any?
55
- hash[:meta] = @_meta unless @_meta.nil?
46
+ hash[:links] = links if links.any?
47
+ hash[:meta] = meta unless meta.nil?
56
48
 
57
49
  hash
58
50
  end
59
51
 
60
52
  def jsonapi_type
61
- @_type
53
+ @_type ||= self.class.type_val || instance_eval(&self.class.type_block)
62
54
  end
63
55
 
64
56
  def jsonapi_id
65
- @_id
57
+ @_id ||= instance_eval(&self.class.id_block)
66
58
  end
67
59
 
68
60
  def jsonapi_related(include)
@@ -74,6 +66,7 @@ module JSONAPI
74
66
  private
75
67
 
76
68
  def attributes(fields)
69
+ @_attributes ||= {}
77
70
  self.class.attribute_blocks
78
71
  .select { |k, _| !@_attributes.key?(k) && fields.include?(k) }
79
72
  .each { |k, v| @_attributes[k] = instance_eval(&v) }
@@ -81,12 +74,31 @@ module JSONAPI
81
74
  end
82
75
 
83
76
  def relationships(fields, include)
77
+ @_relationships ||= self.class.relationship_blocks
78
+ .each_with_object({}) do |(k, v), h|
79
+ h[k] = Relationship.new(@_param_hash, &v)
80
+ end
84
81
  @_relationships
85
82
  .select { |k, _| fields.include?(k) }
86
83
  .each_with_object({}) do |(k, v), h|
87
84
  h[k] = v.as_jsonapi(include.include?(k))
88
85
  end
89
86
  end
87
+
88
+ def meta
89
+ @_meta ||=
90
+ if self.class.meta_val
91
+ self.class.meta_val
92
+ elsif self.class.meta_block
93
+ instance_eval(&self.class.meta_block)
94
+ end
95
+ end
96
+
97
+ def links
98
+ @_links ||= self.class.link_blocks.each_with_object({}) do |(k, v), h|
99
+ h[k] = Link.as_jsonapi(@_param_hash, &v)
100
+ end
101
+ end
90
102
  end
91
103
  end
92
104
  end
@@ -1,2 +1,3 @@
1
1
  require 'jsonapi/serializable/error'
2
+ require 'jsonapi/serializable/model'
2
3
  require 'jsonapi/serializable/resource'
metadata CHANGED
@@ -1,29 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-serializable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1.beta1
4
+ version: 0.1.1.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Hosseini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-02 00:00:00.000000000 Z
11
+ date: 2016-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jsonapi-renderer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.1.beta2
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.1.beta2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
15
43
  requirement: !ruby/object:Gem::Requirement
16
44
  requirements:
17
45
  - - "~>"
18
46
  - !ruby/object:Gem::Version
19
- version: '0.1'
20
- type: :runtime
47
+ version: '3.4'
48
+ type: :development
21
49
  prerelease: false
22
50
  version_requirements: !ruby/object:Gem::Requirement
23
51
  requirements:
24
52
  - - "~>"
25
53
  - !ruby/object:Gem::Version
26
- version: '0.1'
54
+ version: '3.4'
27
55
  description: DSL for building resource classes to be rendered by jsonapi-renderer.
28
56
  email: lucas.hosseini@gmail.com
29
57
  executables: []
@@ -35,6 +63,8 @@ files:
35
63
  - lib/jsonapi/serializable/error.rb
36
64
  - lib/jsonapi/serializable/error_dsl.rb
37
65
  - lib/jsonapi/serializable/link.rb
66
+ - lib/jsonapi/serializable/model.rb
67
+ - lib/jsonapi/serializable/model_dsl.rb
38
68
  - lib/jsonapi/serializable/relationship.rb
39
69
  - lib/jsonapi/serializable/relationship_dsl.rb
40
70
  - lib/jsonapi/serializable/resource.rb