jsonapi-rails 0.1.1.beta1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 149fb06216ef18af6baa06e71acca5d6fa7cbeda
4
+ data.tar.gz: b83bbdc7d9d5739a7361eb294b28b1b1ff53a8d2
5
+ SHA512:
6
+ metadata.gz: 785524db1f37f2b08fb6f2c96d1811f8ba5364dfc7ae92a3d1b47c211a44f88fc4ab85575e70bbc2fd0c56a640f8a1fa199adea2debff6a07b591370df1078df
7
+ data.tar.gz: 4672480284c03e809ecbb527aa8cad84593ef358e936182a1c3ae17aaea19ddad0ad27ed5f6ba817b6d52791cb11099d4523ff8cb37bca3621cd2657fd4b80d4
@@ -0,0 +1,37 @@
1
+ # jsonapi-rails
2
+ Rails plugin for building/consuming [JSON API](http://jsonapi.org) documents.
3
+
4
+ ## Installation
5
+
6
+ Add the following to your application's Gemfile:
7
+ ```ruby
8
+ gem 'jsonapi-rails'
9
+ ```
10
+ And then execute:
11
+ ```
12
+ $ bundle
13
+ ```
14
+ Or install it manually as:
15
+ ```
16
+ $ gem install jsonapi-rails
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ TODO
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork the [official repository](https://github.com/beauby/jsonapi-rails).
26
+ 2. Make your changes in a topic branch.
27
+ 3. Send a pull request.
28
+
29
+ Notes:
30
+
31
+ * Contributions without tests won't be accepted.
32
+ * Please don't update the Gem version.
33
+
34
+ ## License
35
+
36
+ It is free software, and may be redistributed under the terms specified in the
37
+ [LICENSE](LICENSE) file.
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Generates a deserializable resource for the given model.
3
+
4
+ Example:
5
+ `rails generate jsonapi:deserializable User`
@@ -0,0 +1,55 @@
1
+ module Jsonapi
2
+ class DeserializableGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ # TODO(beauby): Implement generator-level whitelisting.
6
+ # TODO(beauby): Implement versioning.
7
+
8
+ def copy_deserializable_file
9
+ template 'deserializable.rb.erb',
10
+ File.join('app/deserializable', class_path,
11
+ "deserializable_#{file_name}.rb")
12
+ end
13
+
14
+ private
15
+
16
+ def model_klass
17
+ # TODO(beauby): Ensure the model class exists.
18
+ class_name.safe_constantize
19
+ end
20
+
21
+ def attr_names
22
+ attrs = model_klass.new.attribute_names - %w(id created_at updated_at)
23
+ fk_attrs = model_klass.reflect_on_all_associations(:belongs_to)
24
+ .map(&:foreign_key)
25
+ attrs - fk_attrs
26
+ end
27
+
28
+ def has_one_rels
29
+ has_one = model_klass.reflect_on_all_associations(:has_one)
30
+ belongs_to = model_klass.reflect_on_all_associations(:belongs_to)
31
+
32
+ has_one + belongs_to
33
+ end
34
+
35
+ def has_one_id_field_name(rel_name)
36
+ "#{rel_name}_id"
37
+ end
38
+
39
+ def has_one_type_field_name(rel_name)
40
+ "#{rel_name}_type"
41
+ end
42
+
43
+ def has_many_rels
44
+ model_klass.reflect_on_all_associations(:has_many)
45
+ end
46
+
47
+ def has_many_id_field_name(rel_name)
48
+ "#{rel_name.to_s.singularize}_ids"
49
+ end
50
+
51
+ def has_many_type_field_name(rel_name)
52
+ "#{rel_name.to_s.singularize}_types"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ <% module_namespacing do -%>
2
+ class Deserializable<%= class_name %> < JSONAPI::Deserializable::Resource
3
+ id
4
+
5
+ <% attr_names.each do |attr| -%>
6
+ attribute :<%= attr %>
7
+ <% end -%>
8
+
9
+ <% has_one_rels.each do |reflection| -%>
10
+ has_one :<%= reflection.name %> do
11
+ field :<%= has_one_id_field_name(reflection.name) %> do |rel|
12
+ rel['data'] && rel['data']['id']
13
+ end
14
+ <% if reflection.polymorphic? -%>
15
+ field :<%= has_one_type_field_name(reflection.name) %> do
16
+ rel['data'] && rel['data']['type']
17
+ end
18
+ <% end -%>
19
+ end
20
+ <% end -%>
21
+ <% has_many_rels.each do |reflection| -%>
22
+ has_many :<%= reflection.name %> do
23
+ field :<%= has_many_id_field_name(reflection.name) %> do |rel|
24
+ rel['data'].map { |ri| ri['id'] }
25
+ end
26
+ <% if reflection.polymorphic? -%>
27
+ field :<%= has_one_type_field_name(reflection.name) %> do
28
+ rel['data'].map { |ri| ri['type'] }
29
+ end
30
+ <% end -%>
31
+ end
32
+ <% end -%>
33
+ end
34
+ <% end -%>
@@ -0,0 +1,34 @@
1
+ <% module_namespacing do -%>
2
+ class Deserializable<%= class_name %> < JSONAPI::Deserializable::Model
3
+ id
4
+
5
+ <% attr_names.each do |attr| -%>
6
+ attribute :<%= attr %>
7
+ <% end -%>
8
+
9
+ <% has_one_rel_names.each do |name, reflection| -%>
10
+ has_one :<%= name %> do
11
+ field :<%= has_one_id_field_name(name) %> do |rel|
12
+ rel['data'] && rel['data']['id']
13
+ end
14
+ <% if reflection.polymorphic? -%>
15
+ field :<%= has_one_type_field_name(name) %> do
16
+ rel['data'] && rel['data']['type']
17
+ end
18
+ <% end -%>
19
+ end
20
+ <% end -%>
21
+ <% has_many_rel_names.each do |rel| -%>
22
+ has_many :<%= rel %> do
23
+ field :<%= has_many_id_field_name(name) %> do |rel|
24
+ rel['data'].map { |ri| ri['id'] }
25
+ end
26
+ <% if reflection.polymorphic? -%>
27
+ field :<%= has_one_type_field_name(name) %> do
28
+ rel['data'].map { |ri| ri['type'] }
29
+ end
30
+ <% end -%>
31
+ end
32
+ <% end -%>
33
+ end
34
+ <% end -%>
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Generates a serializable resource for the given model.
3
+
4
+ Example:
5
+ `rails generate jsonapi:serializable User`
@@ -0,0 +1,41 @@
1
+ module Jsonapi
2
+ class SerializableGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ # TODO(beauby): Implement generator-level whitelisting.
6
+ # TODO(beauby): Implement versioning.
7
+
8
+ def copy_serializable_file
9
+ template 'serializable.rb.erb',
10
+ File.join('app/serializable', class_path,
11
+ "serializable_#{file_name}.rb")
12
+ end
13
+
14
+ private
15
+
16
+ def model_klass
17
+ # TODO(beauby): Ensure the model class exists.
18
+ class_name.safe_constantize
19
+ end
20
+
21
+ def type
22
+ model_klass.name.underscore.pluralize
23
+ end
24
+
25
+ def attr_names
26
+ attrs = model_klass.new.attribute_names - ['id']
27
+ fk_attrs = model_klass.reflect_on_all_associations(:belongs_to)
28
+ .map(&:foreign_key)
29
+ attrs - fk_attrs
30
+ end
31
+
32
+ def has_one_rel_names
33
+ model_klass.reflect_on_all_associations(:has_one).map(&:name) +
34
+ model_klass.reflect_on_all_associations(:belongs_to).map(&:name)
35
+ end
36
+
37
+ def has_many_rel_names
38
+ model_klass.reflect_on_all_associations(:has_many).map(&:name)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ <% module_namespacing do -%>
2
+ <%
3
+ # Blah blah
@@ -0,0 +1,16 @@
1
+ <% module_namespacing do -%>
2
+ class Serializable<%= class_name %> < JSONAPI::Serializable::Model
3
+ type '<%= type %>'
4
+
5
+ <% attr_names.each do |attr| -%>
6
+ attribute :<%= attr %>
7
+ <% end -%>
8
+
9
+ <% has_one_rel_names.each do |rel| -%>
10
+ has_one :<%= rel %>
11
+ <% end -%>
12
+ <% has_many_rel_names.each do |rel| -%>
13
+ has_many :<%= rel %>
14
+ <% end -%>
15
+ end
16
+ <% end -%>
@@ -0,0 +1,5 @@
1
+ class SerializableGenerator < Rails::Generator::Base
2
+ def create_serializable_file
3
+ create_file
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ require 'jsonapi/parser'
2
+ require 'jsonapi/renderer'
3
+
4
+ require 'jsonapi/deserializable'
5
+ require 'jsonapi/serializable'
6
+
7
+ require 'jsonapi/rails/serializable/model_extensions'
8
+ require 'jsonapi/rails/deserializable/resource_extensions'
9
+
10
+ require 'jsonapi/rails/railtie'
@@ -0,0 +1,20 @@
1
+ require 'jsonapi/deserializable/model'
2
+
3
+ module JSONAPI
4
+ module Rails
5
+ module Deserializable
6
+ module ModelExtensions
7
+ def initialize(params = {})
8
+ params[:url_helper] ||= ::Rails.application.routes.url_helpers
9
+ super(params)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ module Serializable
16
+ class Model
17
+ prepend JSONAPI::Rails::Serializable::ModelExtensions
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ require 'jsonapi/deserializable/resource'
2
+
3
+ module JSONAPI
4
+ module Rails
5
+ module Deserializable
6
+ module ResourceExtensions
7
+ def deserialize_has_one_rel!(rel, &block)
8
+ id = rel['data'] && rel['data']['id']
9
+ type = rel['data'] && rel['data']['type'].singularize.camelize
10
+ instance_exec(rel, id, type, &block)
11
+ end
12
+
13
+ def deserialize_has_many_rel!(rel, &block)
14
+ ids = rel['data'].map { |ri| ri['id'] }
15
+ types = rel['data'].map { |ri| ri['type'].singularize.camelize }
16
+ instance_exec(rel, ids, types, &block)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ module Deserializable
23
+ class Resource
24
+ prepend JSONAPI::Rails::Deserializable::ResourceExtensions
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ require 'jsonapi/parser'
2
+
3
+ module JSONAPI
4
+ module Rails
5
+ module_function
6
+
7
+ def parser
8
+ lambda do |body|
9
+ data = JSON.parse(body)
10
+ JSONAPI.parse_resource!(body)
11
+ data = { _json: data } unless data.is_a?(Hash)
12
+ data.with_indifferent_access
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ require 'rails/railtie'
2
+ require 'action_controller'
3
+ require 'action_controller/railtie'
4
+
5
+ require 'jsonapi/rails/parser'
6
+ require 'jsonapi/rails/render'
7
+
8
+ module JSONAPI
9
+ module Rails
10
+ class Railtie < ::Rails::Railtie
11
+ MEDIA_TYPE = 'application/vnd.api+json'.freeze
12
+ HEADERS = {
13
+ response: { 'CONTENT_TYPE'.freeze => MEDIA_TYPE },
14
+ request: { 'ACCEPT'.freeze => MEDIA_TYPE }
15
+ }.freeze
16
+ PARSER = JSONAPI::Rails.parser
17
+
18
+ initializer 'JSONAPI::Rails.initialize' do
19
+ Mime::Type.register MEDIA_TYPE, :jsonapi
20
+ if ::Rails::VERSION::MAJOR >= 5
21
+ ActionDispatch::Request.parameter_parsers[:jsonapi] = PARSER
22
+ else
23
+ ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:jsonapi]] = PARSER
24
+ end
25
+ ActionController::Renderers.add :jsonapi do |json, options|
26
+ unless json.is_a?(String)
27
+ json = JSONAPI::Rails.render(json, options)
28
+ .to_json(options)
29
+ end
30
+ self.content_type ||= Mime[:jsonapi]
31
+ self.response_body = json
32
+ end
33
+
34
+ # TODO(beauby): Add renderer for `jsonapi_errors`.
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ require 'jsonapi/renderer'
2
+ require 'jsonapi/serializable/model'
3
+
4
+ module JSONAPI
5
+ module Rails
6
+ module_function
7
+
8
+ def render(resources, options)
9
+ unless resources.respond_to?(:jsonapi_type)
10
+ resources = serializable_resources_for(resources)
11
+ end
12
+ JSONAPI::Renderer.new(resources, options).as_json
13
+ end
14
+
15
+ def serializable_resources_for(resources)
16
+ if resources.respond_to?(:each)
17
+ resources.map { |r| serializable_model_for(r) }
18
+ else
19
+ serializable_model_for(resources)
20
+ end
21
+ end
22
+
23
+ def serializable_model_for(model)
24
+ serializable_klass_for(model).new(model: model)
25
+ end
26
+
27
+ def serializable_klass_for(model)
28
+ # TODO(beauby): Move resource inference on class level in
29
+ # jsonapi-serializable.
30
+ JSONAPI::Serializable::Model.new.resource_klass_for(model.class)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ require 'jsonapi/serializable/model'
2
+
3
+ module JSONAPI
4
+ module Rails
5
+ module Serializable
6
+ module ModelExtensions
7
+ def initialize(params = {})
8
+ params[:url_helpers] ||= ::Rails.application.routes.url_helpers
9
+ super(params)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ module Serializable
16
+ class Model
17
+ prepend JSONAPI::Rails::Serializable::ModelExtensions
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module JSONAPI
2
+ module Rails
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :jsonapi_rails do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jsonapi-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1.beta1
5
+ platform: ruby
6
+ authors:
7
+ - L. Preston Sego III
8
+ - Lucas Hosseini
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-10-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: jsonapi-renderer
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '='
19
+ - !ruby/object:Gem::Version
20
+ version: 0.1.1.beta2
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '='
26
+ - !ruby/object:Gem::Version
27
+ version: 0.1.1.beta2
28
+ - !ruby/object:Gem::Dependency
29
+ name: jsonapi-parser
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '='
33
+ - !ruby/object:Gem::Version
34
+ version: 0.1.1.beta3
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '='
40
+ - !ruby/object:Gem::Version
41
+ version: 0.1.1.beta3
42
+ - !ruby/object:Gem::Dependency
43
+ name: jsonapi-serializable
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '='
47
+ - !ruby/object:Gem::Version
48
+ version: 0.1.1.beta2
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '='
54
+ - !ruby/object:Gem::Version
55
+ version: 0.1.1.beta2
56
+ - !ruby/object:Gem::Dependency
57
+ name: jsonapi-deserializable
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '='
61
+ - !ruby/object:Gem::Version
62
+ version: 0.1.1.beta3
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.1.1.beta3
70
+ - !ruby/object:Gem::Dependency
71
+ name: activerecord
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '5'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '5'
84
+ - !ruby/object:Gem::Dependency
85
+ name: sqlite3
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.3.12
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 1.3.12
98
+ - !ruby/object:Gem::Dependency
99
+ name: rake
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0.9'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0.9'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rspec
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '3.4'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '3.4'
126
+ description: Efficiently build and consume JSONAPI documents.
127
+ email:
128
+ - LPSego3+dev@gmail.com
129
+ - lucas.hosseini@gmail.com
130
+ executables: []
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - README.md
135
+ - lib/generators/jsonapi/deserializable/USAGE
136
+ - lib/generators/jsonapi/deserializable/deserializable_generator.rb
137
+ - lib/generators/jsonapi/deserializable/serializable_generator.rb
138
+ - lib/generators/jsonapi/deserializable/templates/deserializable.rb.erb
139
+ - lib/generators/jsonapi/deserializable/templates/serializable.rb
140
+ - lib/generators/jsonapi/deserializable/templates/serializable.rb.erb
141
+ - lib/generators/jsonapi/serializable/USAGE
142
+ - lib/generators/jsonapi/serializable/serializable_generator.rb
143
+ - lib/generators/jsonapi/serializable/templates/serializable.rb
144
+ - lib/generators/jsonapi/serializable/templates/serializable.rb.erb
145
+ - lib/generators/serializable_generator.rb
146
+ - lib/jsonapi/rails.rb
147
+ - lib/jsonapi/rails/deserializable/model_extensions.rb
148
+ - lib/jsonapi/rails/deserializable/resource_extensions.rb
149
+ - lib/jsonapi/rails/parser.rb
150
+ - lib/jsonapi/rails/railtie.rb
151
+ - lib/jsonapi/rails/render.rb
152
+ - lib/jsonapi/rails/serializable/model_extensions.rb
153
+ - lib/jsonapi/rails/version.rb
154
+ - lib/tasks/jsonapi/rails_tasks.rake
155
+ homepage: https://github.com/beauby/jsonapi-rails
156
+ licenses:
157
+ - MIT
158
+ metadata: {}
159
+ post_install_message:
160
+ rdoc_options: []
161
+ require_paths:
162
+ - lib
163
+ required_ruby_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">"
171
+ - !ruby/object:Gem::Version
172
+ version: 1.3.1
173
+ requirements: []
174
+ rubyforge_project:
175
+ rubygems_version: 2.5.1
176
+ signing_key:
177
+ specification_version: 4
178
+ summary: Rails plugin for (de)serialization of JSONAPI resources
179
+ test_files: []