jsonapi-serializable 0.1.1.beta1 → 0.1.1.beta2

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: 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