jsonapi-rails 0.1.1.beta4 → 0.1.1

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: f0e8e67bf5e4b3dd0ba9c9a3cf32325bfadd1c14
4
- data.tar.gz: 643e26ce20f6f6107752ee0a4df1e0eccfc633f1
3
+ metadata.gz: d03b1dcb88e6112b5b8c82e1fb400ce802fe66a5
4
+ data.tar.gz: cf69d3e19c4e73a5cdf1b7543e0620ee2f6d4504
5
5
  SHA512:
6
- metadata.gz: d7845abcc10f12cc53d941a4bb271a3137c938dc93ff8e0c0fa8fbed5325123dd2e984dea105924dbad7819359e43cf64e596fc88fb2eb68b1203c72ffca3afd
7
- data.tar.gz: be4b0bdcb39e0fc48b497629ffe216b82817bb04e7d6c84b04b0279650b654acc1f6759e4bf3ce632266d6c368801323e0065038475039469a40973752e4a75b
6
+ metadata.gz: 0233e1af894d9227ba5b396c669c500c9f244d258bf6ac66e85936566b93be555837d6be3ecb041b000aa989b6a699ab113eab73fac15c99aa1358bc441569fc
7
+ data.tar.gz: 42665fbd7fc8d29d251573d20fc3a3aba19f03e1390f7bbb86fea6a337e19dc30d9435a29ef48e6474b01da41c1213cca4d5e04c1886dc0f1d475bb6b252e763
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # jsonapi-rails
2
- Rails integration for [jsonapi-rb](https://github.com/jsonapi-rb/jsonapi-rb).
2
+ Rails integration for [jsonapi-rb](http://jsonapi-rb.org).
3
3
 
4
4
  ## Status
5
5
 
6
6
  [![Gem Version](https://badge.fury.io/rb/jsonapi-rails.svg)](https://badge.fury.io/rb/jsonapi-rails)
7
- [![Build Status](https://secure.travis-ci.org/jsonapi-rb/rails.svg?branch=master)](http://travis-ci.org/jsonapi-rb/rails?branch=master)
7
+ [![Build Status](https://secure.travis-ci.org/jsonapi-rb/jsonapi-rails.svg?branch=master)](http://travis-ci.org/jsonapi-rb/rails?branch=master)
8
+ [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/jsonapi-rb/Lobby)
8
9
 
9
10
  ## Installation
10
11
 
@@ -16,85 +17,10 @@ And then execute:
16
17
  ```
17
18
  $ bundle
18
19
  ```
19
- Or install it manually as:
20
- ```
21
- $ gem install jsonapi-rails
22
- ```
23
-
24
- ## Usage
25
-
26
- ### Serialization
27
-
28
- Example:
29
- ```ruby
30
- # app/serializable/serializable_user.rb
31
- class SerializableUser < JSONAPI::Serializable::Model
32
- type 'users'
33
-
34
- attribute :name
35
- attribute :email do
36
- "#{@model.name}@foo.bar"
37
- end
38
-
39
- has_many :posts do
40
- # data is auto-inferred
41
- link(:related) { @url_helpers.user_posts(@model) }
42
- meta foo: :bar
43
- end
44
-
45
- has_many :comments do
46
- data do
47
- @user.comments.order(:desc)
48
- end
49
- end
50
-
51
- has_many :reviews, Foo::Bar::SerializableRev
52
20
 
53
- link(:self) { @url_helpers.user_url(@model.id) }
54
- meta do
55
- { foo: 'bar' }
56
- end
57
- end
21
+ ## Usage and documentation
58
22
 
59
- # app/controllers/users_controller.rb
60
- # ...
61
- user = User.find_by(id: id)
62
- render jsonapi: user, include: { posts: [:comments] }, meta: { foo: 'bar' }
63
- # ...
64
- ```
65
-
66
- ### Deserialization
67
-
68
- Example:
69
- ```ruby
70
- class PostsController < ActionController::Base
71
- deserializable_resource :post, only: [:create, :update] do
72
- attribute :title
73
- attribute :date
74
- has_one :author do |rel, id, type|
75
- field user_id: id
76
- field user_type: type
77
- end
78
- has_many :comments
79
- end
80
-
81
- def create_params
82
- params.require(:user).permit!
83
- end
84
-
85
- def create
86
- create_params[:title]
87
- create_params[:date]
88
- create_params[:comment_ids]
89
- create_params[:comment_types]
90
- create_params[:user_id]
91
- create_params[:user_type]
92
- # ...
93
- end
94
- end
95
-
96
-
97
- ```
23
+ See [jsonapi-rb.org/guides](http://jsonapi-rb.org/guides).
98
24
 
99
25
  ## License
100
26
 
@@ -1,11 +1,9 @@
1
1
  <% module_namespacing do -%>
2
- class Serializable<%= class_name %> < JSONAPI::Serializable::Model
2
+ class Serializable<%= class_name %> < JSONAPI::Serializable::Resource
3
3
  type '<%= type %>'
4
-
5
4
  <% attr_names.each do |attr| -%>
6
5
  attribute :<%= attr %>
7
6
  <% end -%>
8
-
9
7
  <% has_one_rel_names.each do |rel| -%>
10
8
  has_one :<%= rel %>
11
9
  <% end -%>
@@ -1,6 +1,3 @@
1
1
  require 'jsonapi/deserializable'
2
2
  require 'jsonapi/serializable'
3
-
4
- require 'jsonapi/rails/deserializable/resource_extensions'
5
-
6
3
  require 'jsonapi/rails/railtie'
@@ -11,27 +11,27 @@ module JSONAPI
11
11
  end
12
12
 
13
13
  module ClassMethods
14
- def deserializable_resource(key, *args, &block)
15
- klass = args.shift unless args.first.is_a?(Hash)
16
- options = args.first || {}
17
- if klass.nil?
18
- klass = Class.new(JSONAPI::Deserializable::Resource, &block)
19
- end
20
- use DeserializeResource, key, klass, options
14
+ def deserializable_resource(key, options = {}, &block)
15
+ _deserializable(key, options,
16
+ JSONAPI::Deserializable::Resource, &block)
21
17
  end
22
18
 
23
- def deserializable_relationship(key, *args, &block)
24
- klass = args.shift unless args.first.is_a?(Hash)
25
- options = args.first || {}
26
- if klass.nil?
27
- klass = Class.new(JSONAPI::Deserializable::Relationship, &block)
28
- end
29
- use DeserializeResource, key, klass, options
19
+ def deserializable_relationship(key, options = {}, &block)
20
+ _deserializable(key, options,
21
+ JSONAPI::Deserializable::Relationship, &block)
22
+ end
23
+
24
+ # @api private
25
+ def _deserializable(key, options, fallback, &block)
26
+ options = options.dup
27
+ klass = options.delete(:class) || Class.new(fallback, &block)
28
+ use Deserialization, key, klass, options
30
29
  end
31
30
  end
32
31
 
33
- class DeserializationMiddleware
34
- JSONAPI_KEYS = %w(data meta links jsonapi).freeze
32
+ class Deserialization
33
+ REQUEST_PARAMETERS_KEY =
34
+ 'action_dispatch.request.request_parameters'.freeze
35
35
  def initialize(app, key, klass)
36
36
  @app = app
37
37
  @deserializable_key = key
@@ -40,32 +40,15 @@ module JSONAPI
40
40
 
41
41
  def call(env)
42
42
  request = Rack::Request.new(env)
43
- body = request.params.slice(*JSONAPI_KEYS)
44
- parser.parse!(body)
43
+ body = JSON.parse(request.body.read)
45
44
  deserialized_hash = @deserializable_class.call(body)
46
- jsonapi = {}
47
- JSONAPI_KEYS.each do |key|
48
- next unless request.params.key?(key)
49
- jsonapi[key.to_sym] = request.delete_param(key)
45
+ (env[REQUEST_PARAMETERS_KEY] ||= {}).tap do |request_parameters|
46
+ request_parameters[@deserializable_key] = deserialized_hash
50
47
  end
51
- request.update_param(:_jsonapi, jsonapi)
52
- request.update_param(@deserializable_key, deserialized_hash)
53
48
 
54
49
  @app.call(env)
55
50
  end
56
51
  end
57
-
58
- class DeserializeResource < DeserializationMiddleware
59
- def parser
60
- JSONAPI::Parser::Resource
61
- end
62
- end
63
-
64
- class DeserializeRelationship < DeserializationMiddleware
65
- def parser
66
- JSONAPI::Parser::Relationship
67
- end
68
- end
69
52
  end
70
53
  end
71
54
  end
@@ -10,6 +10,10 @@ module JSONAPI
10
10
  class Railtie < ::Rails::Railtie
11
11
  MEDIA_TYPE = 'application/vnd.api+json'.freeze
12
12
  PARSER = JSONAPI::Rails.parser
13
+ RENDERERS = {
14
+ jsonapi: JSONAPI::Rails.rails_renderer(SuccessRenderer),
15
+ jsonapi_error: JSONAPI::Rails.rails_renderer(ErrorRenderer)
16
+ }.freeze
13
17
 
14
18
  initializer 'jsonapi-rails.action_controller' do
15
19
  ActiveSupport.on_load(:action_controller) do
@@ -17,26 +21,29 @@ module JSONAPI
17
21
  include ::JSONAPI::Rails::ActionController
18
22
 
19
23
  Mime::Type.register MEDIA_TYPE, :jsonapi
24
+
20
25
  if ::Rails::VERSION::MAJOR >= 5
21
26
  ::ActionDispatch::Request.parameter_parsers[:jsonapi] = PARSER
22
27
  else
23
28
  ::ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:jsonapi]] = PARSER
24
29
  end
25
30
 
26
- ::ActionController::Renderers.add :jsonapi do |json, options|
27
- unless json.is_a?(String)
28
- json = JSONAPI::Rails::Renderer.render(json, options)
29
- end
30
- self.content_type ||= Mime[:jsonapi]
31
- self.response_body = json
31
+ RENDERERS.each do |key, renderer|
32
+ ::ActionController::Renderers.add(key, &renderer)
32
33
  end
33
34
 
34
- ::ActionController::Renderers.add :jsonapi_errors do |json, options|
35
- unless json.is_a?(String)
36
- json = JSONAPI::Rails::ErrorRender.render_errors(json, options)
35
+ JSONAPI::Deserializable::Resource.configure do |config|
36
+ config.default_has_one do |key, _rel, id, type|
37
+ key = key.to_s.singularize
38
+ type = type.to_s.singularize.camelize
39
+ { "#{key}_id".to_sym => id, "#{key}_type".to_sym => type }
40
+ end
41
+
42
+ config.default_has_many do |key, _rel, ids, types|
43
+ key = key.to_s.singularize
44
+ types = types.map { |t| t.to_s.singularize.camelize }
45
+ { "#{key}_ids".to_sym => ids, "#{key}_types".to_sym => types }
37
46
  end
38
- self.content_type ||= Mime[:jsonapi]
39
- self.response_body = json
40
47
  end
41
48
  end
42
49
  end
@@ -2,15 +2,15 @@ require 'jsonapi/serializable/renderer'
2
2
 
3
3
  module JSONAPI
4
4
  module Rails
5
- class Renderer
5
+ class SuccessRenderer
6
6
  def self.render(resources, options)
7
- # TODO(beauby): handle status option.
8
7
  opts = options.dup
9
8
  # TODO(beauby): Move this to a global configuration.
10
9
  default_exposures = {
11
10
  url_helpers: ::Rails.application.routes.url_helpers
12
11
  }
13
12
  opts[:expose] = default_exposures.merge!(opts[:expose] || {})
13
+ opts[:jsonapi] = opts.delete(:jsonapi_object)
14
14
 
15
15
  JSONAPI::Serializable::Renderer.render(resources, opts)
16
16
  end
@@ -22,5 +22,16 @@ module JSONAPI
22
22
  JSONAPI::Serializable::ErrorRenderer.render(errors, options)
23
23
  end
24
24
  end
25
+
26
+ module_function
27
+
28
+ # @api private
29
+ def rails_renderer(renderer)
30
+ proc do |json, options|
31
+ json = renderer.render(json, options) unless json.is_a?(String)
32
+ self.content_type ||= Mime[:jsonapi]
33
+ self.response_body = json
34
+ end
35
+ end
25
36
  end
26
37
  end
metadata CHANGED
@@ -1,73 +1,73 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1.beta4
4
+ version: 0.1.1
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-11-18 00:00:00.000000000 Z
11
+ date: 2016-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: jsonapi-deserializable
14
+ name: jsonapi-rb
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.1.beta3
19
+ version: 0.1.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.1.beta3
26
+ version: 0.1.1
27
27
  - !ruby/object:Gem::Dependency
28
- name: jsonapi-parser
28
+ name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.1.1.beta3
34
- type: :runtime
33
+ version: '5.0'
34
+ type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.1.1.beta3
40
+ version: '5.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: jsonapi-serializable
42
+ name: sqlite3
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.1.1.beta4
48
- type: :runtime
47
+ version: '0'
48
+ type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.1.1.beta4
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.9'
61
+ version: '11.3'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.9'
68
+ version: '11.3'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: rspec-rails
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dry-validation
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.10'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.10'
83
97
  description: Efficient, convenient, non-intrusive JSONAPI framework for Rails.
84
98
  email:
85
99
  - lucas.hosseini@gmail.com
@@ -88,19 +102,15 @@ extensions: []
88
102
  extra_rdoc_files: []
89
103
  files:
90
104
  - README.md
91
- - lib/generators/jsonapi/deserializable/USAGE
92
- - lib/generators/jsonapi/deserializable/deserializable_generator.rb
93
- - lib/generators/jsonapi/deserializable/templates/deserializable.rb.erb
94
105
  - lib/generators/jsonapi/serializable/USAGE
95
106
  - lib/generators/jsonapi/serializable/serializable_generator.rb
96
107
  - lib/generators/jsonapi/serializable/templates/serializable.rb.erb
97
108
  - lib/jsonapi/rails.rb
98
109
  - lib/jsonapi/rails/action_controller.rb
99
- - lib/jsonapi/rails/deserializable/resource_extensions.rb
100
110
  - lib/jsonapi/rails/parser.rb
101
111
  - lib/jsonapi/rails/railtie.rb
102
112
  - lib/jsonapi/rails/renderer.rb
103
- homepage: https://github.com/jsonapi-rb/rails
113
+ homepage: https://github.com/jsonapi-rb/jsonapi-rails
104
114
  licenses:
105
115
  - MIT
106
116
  metadata: {}
@@ -115,12 +125,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
125
  version: '0'
116
126
  required_rubygems_version: !ruby/object:Gem::Requirement
117
127
  requirements:
118
- - - ">"
128
+ - - ">="
119
129
  - !ruby/object:Gem::Version
120
- version: 1.3.1
130
+ version: '0'
121
131
  requirements: []
122
132
  rubyforge_project:
123
- rubygems_version: 2.5.1
133
+ rubygems_version: 2.6.8
124
134
  signing_key:
125
135
  specification_version: 4
126
136
  summary: jsonapi-rb integrations for Rails.
@@ -1,5 +0,0 @@
1
- Description:
2
- Generates a deserializable resource for the given model.
3
-
4
- Example:
5
- `rails generate jsonapi:deserializable User`
@@ -1,55 +0,0 @@
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
@@ -1,34 +0,0 @@
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 -%>
@@ -1,27 +0,0 @@
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