jsonapi-rails 0.1.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []