lp-serializable 0.1.0 → 0.2.0
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 +4 -4
- data/.ruby-version +1 -0
- data/.travis.yml +2 -0
- data/Gemfile.lock +71 -2
- data/README.md +105 -3
- data/lib/fast_jsonapi/multi_to_json.rb +100 -0
- data/lib/fast_jsonapi/object_serializer.rb +254 -0
- data/lib/fast_jsonapi/serialization_core.rb +192 -0
- data/lib/lp/serializable/utilities.rb +16 -3
- data/lib/lp/serializable/version.rb +1 -1
- data/lib/lp/serializable.rb +4 -3
- data/lp-serializable.gemspec +12 -3
- metadata +136 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ee8c8007befe5042222082f7d355d28d8b5364d0a06499416055c7ff9c2ba24c
|
|
4
|
+
data.tar.gz: 9eeba9747a87355b25f45c013131374be16ff9c2f4a600c55efbf806f93148e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8ec72124b13225234bfcdedb2663f52a5fa474ede7c4a526303d937098e60a1bd7c33342e2e0cfba9f805eb99d82171a9e6e08fb2820b428940ddb5c792febc8
|
|
7
|
+
data.tar.gz: 9d3899a92c259237da9bdca814bcc7ce00938764cd08ec889028466ec83100fba4e5ddd0a7fd9160aed2f4f788bc862ee1123270c9cdce0af7eab9e892485705
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.5.0
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,12 +1,37 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
lp-serializable (0.
|
|
5
|
-
|
|
4
|
+
lp-serializable (0.2.0)
|
|
5
|
+
activesupport (>= 4.2)
|
|
6
|
+
fast_jsonapi (>= 1.2)
|
|
6
7
|
|
|
7
8
|
GEM
|
|
8
9
|
remote: https://rubygems.org/
|
|
9
10
|
specs:
|
|
11
|
+
actionpack (5.2.0)
|
|
12
|
+
actionview (= 5.2.0)
|
|
13
|
+
activesupport (= 5.2.0)
|
|
14
|
+
rack (~> 2.0)
|
|
15
|
+
rack-test (>= 0.6.3)
|
|
16
|
+
rails-dom-testing (~> 2.0)
|
|
17
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
18
|
+
actionview (5.2.0)
|
|
19
|
+
activesupport (= 5.2.0)
|
|
20
|
+
builder (~> 3.1)
|
|
21
|
+
erubi (~> 1.4)
|
|
22
|
+
rails-dom-testing (~> 2.0)
|
|
23
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
24
|
+
active_model_serializers (0.10.7)
|
|
25
|
+
actionpack (>= 4.1, < 6)
|
|
26
|
+
activemodel (>= 4.1, < 6)
|
|
27
|
+
case_transform (>= 0.2)
|
|
28
|
+
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
|
29
|
+
activemodel (5.2.0)
|
|
30
|
+
activesupport (= 5.2.0)
|
|
31
|
+
activerecord (5.2.0)
|
|
32
|
+
activemodel (= 5.2.0)
|
|
33
|
+
activesupport (= 5.2.0)
|
|
34
|
+
arel (>= 9.0)
|
|
10
35
|
activesupport (5.2.0)
|
|
11
36
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
12
37
|
i18n (>= 0.7, < 2)
|
|
@@ -16,23 +41,58 @@ GEM
|
|
|
16
41
|
bundler
|
|
17
42
|
rake
|
|
18
43
|
thor (>= 0.14.0)
|
|
44
|
+
arel (9.0.0)
|
|
45
|
+
benchmark-perf (0.2.1)
|
|
46
|
+
builder (3.2.3)
|
|
47
|
+
byebug (10.0.2)
|
|
48
|
+
case_transform (0.2)
|
|
49
|
+
activesupport
|
|
19
50
|
coderay (1.1.2)
|
|
20
51
|
concurrent-ruby (1.0.5)
|
|
52
|
+
crass (1.0.4)
|
|
21
53
|
diff-lcs (1.3)
|
|
54
|
+
erubi (1.7.1)
|
|
22
55
|
fast_jsonapi (1.2)
|
|
23
56
|
activesupport (>= 4.2)
|
|
24
57
|
i18n (1.0.1)
|
|
25
58
|
concurrent-ruby (~> 1.0)
|
|
59
|
+
jsonapi-deserializable (0.2.0)
|
|
60
|
+
jsonapi-rb (0.5.0)
|
|
61
|
+
jsonapi-deserializable (~> 0.2.0)
|
|
62
|
+
jsonapi-serializable (~> 0.3.0)
|
|
63
|
+
jsonapi-renderer (0.2.0)
|
|
64
|
+
jsonapi-serializable (0.3.0)
|
|
65
|
+
jsonapi-renderer (~> 0.2.0)
|
|
66
|
+
jsonapi-serializers (1.0.1)
|
|
67
|
+
activesupport
|
|
68
|
+
loofah (2.2.2)
|
|
69
|
+
crass (~> 1.0.2)
|
|
70
|
+
nokogiri (>= 1.5.9)
|
|
26
71
|
method_source (0.9.0)
|
|
72
|
+
mini_portile2 (2.3.0)
|
|
27
73
|
minitest (5.11.3)
|
|
74
|
+
nokogiri (1.8.4)
|
|
75
|
+
mini_portile2 (~> 2.3.0)
|
|
76
|
+
oj (3.6.3)
|
|
28
77
|
pry (0.11.3)
|
|
29
78
|
coderay (~> 1.1.0)
|
|
30
79
|
method_source (~> 0.9.0)
|
|
80
|
+
rack (2.0.5)
|
|
81
|
+
rack-test (1.0.0)
|
|
82
|
+
rack (>= 1.0, < 3)
|
|
83
|
+
rails-dom-testing (2.0.3)
|
|
84
|
+
activesupport (>= 4.2.0)
|
|
85
|
+
nokogiri (>= 1.6)
|
|
86
|
+
rails-html-sanitizer (1.0.4)
|
|
87
|
+
loofah (~> 2.2, >= 2.2.2)
|
|
31
88
|
rake (10.5.0)
|
|
32
89
|
rspec (3.7.0)
|
|
33
90
|
rspec-core (~> 3.7.0)
|
|
34
91
|
rspec-expectations (~> 3.7.0)
|
|
35
92
|
rspec-mocks (~> 3.7.0)
|
|
93
|
+
rspec-benchmark (0.3.0)
|
|
94
|
+
benchmark-perf (~> 0.2.0)
|
|
95
|
+
rspec (>= 3.0.0, < 4.0.0)
|
|
36
96
|
rspec-core (3.7.1)
|
|
37
97
|
rspec-support (~> 3.7.0)
|
|
38
98
|
rspec-expectations (3.7.0)
|
|
@@ -42,6 +102,7 @@ GEM
|
|
|
42
102
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
43
103
|
rspec-support (~> 3.7.0)
|
|
44
104
|
rspec-support (3.7.1)
|
|
105
|
+
sqlite3 (1.3.13)
|
|
45
106
|
thor (0.20.0)
|
|
46
107
|
thread_safe (0.3.6)
|
|
47
108
|
tzinfo (1.2.5)
|
|
@@ -51,12 +112,20 @@ PLATFORMS
|
|
|
51
112
|
ruby
|
|
52
113
|
|
|
53
114
|
DEPENDENCIES
|
|
115
|
+
active_model_serializers (~> 0.10.7)
|
|
116
|
+
activerecord (>= 4.2)
|
|
54
117
|
appraisal
|
|
55
118
|
bundler (~> 1.16)
|
|
119
|
+
byebug
|
|
120
|
+
jsonapi-rb (~> 0.5.0)
|
|
121
|
+
jsonapi-serializers (~> 1.0.0)
|
|
56
122
|
lp-serializable!
|
|
123
|
+
oj (~> 3.3)
|
|
57
124
|
pry
|
|
58
125
|
rake (~> 10.0)
|
|
59
126
|
rspec (~> 3.0)
|
|
127
|
+
rspec-benchmark (~> 0.3.0)
|
|
128
|
+
sqlite3 (~> 1.3)
|
|
60
129
|
|
|
61
130
|
BUNDLED WITH
|
|
62
131
|
1.16.1
|
data/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Lp::Serializable
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
When serializing with [fast_jsonapi](https://github.com/Netflix/fast_jsonapi), data is structured per the json-api [specs](http://jsonapi.org/format/).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
lp-serializable is a thin wrapper around fast_jsonapi serialization, producting AMS style output.
|
|
6
|
+
|
|
7
|
+
lp-serializable is intended to be used in Rails controllers.
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
@@ -22,7 +24,107 @@ Or install it yourself as:
|
|
|
22
24
|
|
|
23
25
|
## Usage
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
### Controller Definition
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
class ApplicationController < ActionController::Base
|
|
31
|
+
include Lp::Serializable
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class MoviesController < ApplicationController
|
|
35
|
+
def index
|
|
36
|
+
movies = Movie.all
|
|
37
|
+
movies_hash = serialize_and_flatten_collection(movies, 'Movie')
|
|
38
|
+
render json: movies_hash
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def show
|
|
42
|
+
movie = Movie.find(params[:id])
|
|
43
|
+
movie_hash = serialize_and_flatten(movie)
|
|
44
|
+
render json: movie
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Serializer Definition
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
class MovieSerializer
|
|
53
|
+
include FastJsonapi::ObjectSerializer
|
|
54
|
+
|
|
55
|
+
attributes :name, :year
|
|
56
|
+
|
|
57
|
+
has_many :actors
|
|
58
|
+
belongs_to :owner
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class ActorSerializer
|
|
62
|
+
include FastJsonapi::ObjectSerializer
|
|
63
|
+
|
|
64
|
+
attributes :id
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class OwnerSerializer
|
|
68
|
+
include FastJsonapi::ObjectSerializer
|
|
69
|
+
|
|
70
|
+
attributes :id
|
|
71
|
+
end
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Sample Object
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
movie = Movie.new
|
|
78
|
+
movie.id = 232
|
|
79
|
+
movie.name = 'test movie'
|
|
80
|
+
movie.actor_ids = [1, 2, 3]
|
|
81
|
+
movie.owner_id = 3
|
|
82
|
+
movie.movie_type_id = 1
|
|
83
|
+
movie
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Object Serialization
|
|
87
|
+
|
|
88
|
+
#### Return a hash
|
|
89
|
+
```ruby
|
|
90
|
+
hash = serialize_and_flatten(movie)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### Output
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"data": {
|
|
98
|
+
"id": "3",
|
|
99
|
+
"type": "movie",
|
|
100
|
+
"name": "test movie",
|
|
101
|
+
"year": null,
|
|
102
|
+
"actors": [
|
|
103
|
+
{
|
|
104
|
+
"id": "1",
|
|
105
|
+
"type": "actor"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "2",
|
|
109
|
+
"type": "actor"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"owner": {
|
|
113
|
+
"id": "3",
|
|
114
|
+
"type": "user"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For more information on configuration, refer to [fast_jsonapi](https://github.com/Netflix/fast_jsonapi#customizable-options) documentation.
|
|
122
|
+
|
|
123
|
+
## Options Support
|
|
124
|
+
|
|
125
|
+
lp-serializable does not currently support fast_jsonapi's options hash when instantiating serializers.
|
|
126
|
+
|
|
127
|
+
This affects serializing with [params](https://github.com/Netflix/fast_jsonapi#params), [compound documents](https://github.com/Netflix/fast_jsonapi#compound-document), metadata, and links.
|
|
26
128
|
|
|
27
129
|
## Development
|
|
28
130
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
# Usage:
|
|
6
|
+
# class Movie
|
|
7
|
+
# def to_json(payload)
|
|
8
|
+
# FastJsonapi::MultiToJson.to_json(payload)
|
|
9
|
+
# end
|
|
10
|
+
# end
|
|
11
|
+
module FastJsonapi
|
|
12
|
+
module MultiToJson
|
|
13
|
+
# Result object pattern is from https://johnnunemaker.com/resilience-in-ruby/
|
|
14
|
+
# e.g. https://github.com/github/github-ds/blob/fbda5389711edfb4c10b6c6bad19311dfcb1bac1/lib/github/result.rb
|
|
15
|
+
class Result
|
|
16
|
+
def initialize(*rescued_exceptions)
|
|
17
|
+
@rescued_exceptions = if rescued_exceptions.empty?
|
|
18
|
+
[StandardError]
|
|
19
|
+
else
|
|
20
|
+
rescued_exceptions
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
@value = yield
|
|
24
|
+
@error = nil
|
|
25
|
+
rescue *rescued_exceptions => e
|
|
26
|
+
@error = e
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def ok?
|
|
30
|
+
@error.nil?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def value!
|
|
34
|
+
if ok?
|
|
35
|
+
@value
|
|
36
|
+
else
|
|
37
|
+
raise @error
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def rescue
|
|
42
|
+
return self if ok?
|
|
43
|
+
|
|
44
|
+
Result.new(*@rescued_exceptions) { yield(@error) }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.logger(device=nil)
|
|
49
|
+
return @logger = Logger.new(device) if device
|
|
50
|
+
@logger ||= Logger.new(IO::NULL)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Encoder-compatible with default MultiJSON adapters and defaults
|
|
54
|
+
def self.to_json_method
|
|
55
|
+
encode_method = String.new(%(def _fast_to_json(object)\n ))
|
|
56
|
+
encode_method << Result.new(LoadError) {
|
|
57
|
+
require 'oj'
|
|
58
|
+
%(::Oj.dump(object, mode: :compat, time_format: :ruby, use_to_json: true))
|
|
59
|
+
}.rescue {
|
|
60
|
+
require 'yajl'
|
|
61
|
+
%(::Yajl::Encoder.encode(object))
|
|
62
|
+
}.rescue {
|
|
63
|
+
require 'jrjackson' unless defined?(::JrJackson)
|
|
64
|
+
%(::JrJackson::Json.dump(object))
|
|
65
|
+
}.rescue {
|
|
66
|
+
require 'json'
|
|
67
|
+
%(JSON.fast_generate(object, create_additions: false, quirks_mode: true))
|
|
68
|
+
}.rescue {
|
|
69
|
+
require 'gson'
|
|
70
|
+
%(::Gson::Encoder.new({}).encode(object))
|
|
71
|
+
}.rescue {
|
|
72
|
+
require 'active_support/json/encoding'
|
|
73
|
+
%(::ActiveSupport::JSON.encode(object))
|
|
74
|
+
}.rescue {
|
|
75
|
+
warn "No JSON encoder found. Falling back to `object.to_json`"
|
|
76
|
+
%(object.to_json)
|
|
77
|
+
}.value!
|
|
78
|
+
encode_method << "\nend"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.to_json(object)
|
|
82
|
+
_fast_to_json(object)
|
|
83
|
+
rescue NameError
|
|
84
|
+
define_to_json(FastJsonapi::MultiToJson)
|
|
85
|
+
_fast_to_json(object)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def self.define_to_json(receiver)
|
|
89
|
+
cl = caller_locations[0]
|
|
90
|
+
method_body = to_json_method
|
|
91
|
+
logger.debug { "Defining #{receiver}._fast_to_json as #{method_body.inspect}" }
|
|
92
|
+
receiver.instance_eval method_body, cl.absolute_path, cl.lineno
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def self.reset_to_json!
|
|
96
|
+
undef :_fast_to_json if method_defined?(:_fast_to_json)
|
|
97
|
+
logger.debug { "Undefining #{receiver}._fast_to_json" }
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/object'
|
|
4
|
+
require 'active_support/concern'
|
|
5
|
+
require 'active_support/inflector'
|
|
6
|
+
require 'fast_jsonapi/serialization_core'
|
|
7
|
+
|
|
8
|
+
module FastJsonapi
|
|
9
|
+
module ObjectSerializer
|
|
10
|
+
extend ActiveSupport::Concern
|
|
11
|
+
include SerializationCore
|
|
12
|
+
|
|
13
|
+
SERIALIZABLE_HASH_NOTIFICATION = 'render.fast_jsonapi.serializable_hash'
|
|
14
|
+
SERIALIZED_JSON_NOTIFICATION = 'render.fast_jsonapi.serialized_json'
|
|
15
|
+
|
|
16
|
+
included do
|
|
17
|
+
# Set record_type based on the name of the serializer class
|
|
18
|
+
set_type(reflected_record_type) if reflected_record_type
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def initialize(resource, options = {})
|
|
22
|
+
process_options(options)
|
|
23
|
+
|
|
24
|
+
@resource = resource
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def serializable_hash
|
|
28
|
+
return hash_for_collection if is_collection?(@resource)
|
|
29
|
+
|
|
30
|
+
hash_for_one_record
|
|
31
|
+
end
|
|
32
|
+
alias_method :to_hash, :serializable_hash
|
|
33
|
+
|
|
34
|
+
def hash_for_one_record
|
|
35
|
+
serializable_hash = { data: nil }
|
|
36
|
+
serializable_hash[:meta] = @meta if @meta.present?
|
|
37
|
+
serializable_hash[:links] = @links if @links.present?
|
|
38
|
+
|
|
39
|
+
return serializable_hash unless @resource
|
|
40
|
+
|
|
41
|
+
serializable_hash[:data] = self.class.record_hash(@resource, @params)
|
|
42
|
+
serializable_hash[:included] = self.class.get_included_records(@resource, @includes, @known_included_objects, @params) if @includes.present?
|
|
43
|
+
serializable_hash
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def hash_for_collection
|
|
47
|
+
serializable_hash = {}
|
|
48
|
+
|
|
49
|
+
data = []
|
|
50
|
+
included = []
|
|
51
|
+
@resource.each do |record|
|
|
52
|
+
data << self.class.record_hash(record, @params)
|
|
53
|
+
included.concat self.class.get_included_records(record, @includes, @known_included_objects, @params) if @includes.present?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
serializable_hash[:data] = data
|
|
57
|
+
serializable_hash[:included] = included if @includes.present?
|
|
58
|
+
serializable_hash[:meta] = @meta if @meta.present?
|
|
59
|
+
serializable_hash[:links] = @links if @links.present?
|
|
60
|
+
serializable_hash
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def serialized_json
|
|
64
|
+
self.class.to_json(serializable_hash)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def process_options(options)
|
|
70
|
+
return if options.blank?
|
|
71
|
+
|
|
72
|
+
@known_included_objects = {}
|
|
73
|
+
@meta = options[:meta]
|
|
74
|
+
@links = options[:links]
|
|
75
|
+
@params = options[:params] || {}
|
|
76
|
+
raise ArgumentError.new("`params` option passed to serializer must be a hash") unless @params.is_a?(Hash)
|
|
77
|
+
|
|
78
|
+
if options[:include].present?
|
|
79
|
+
@includes = options[:include].delete_if(&:blank?).map(&:to_sym)
|
|
80
|
+
self.class.validate_includes!(@includes)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def is_collection?(resource)
|
|
85
|
+
resource.respond_to?(:each) && !resource.respond_to?(:each_pair)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class_methods do
|
|
89
|
+
|
|
90
|
+
def inherited(subclass)
|
|
91
|
+
super(subclass)
|
|
92
|
+
subclass.attributes_to_serialize = attributes_to_serialize.dup if attributes_to_serialize.present?
|
|
93
|
+
subclass.relationships_to_serialize = relationships_to_serialize.dup if relationships_to_serialize.present?
|
|
94
|
+
subclass.cachable_relationships_to_serialize = cachable_relationships_to_serialize.dup if cachable_relationships_to_serialize.present?
|
|
95
|
+
subclass.uncachable_relationships_to_serialize = uncachable_relationships_to_serialize.dup if uncachable_relationships_to_serialize.present?
|
|
96
|
+
subclass.transform_method = transform_method
|
|
97
|
+
subclass.cache_length = cache_length
|
|
98
|
+
subclass.race_condition_ttl = race_condition_ttl
|
|
99
|
+
subclass.data_links = data_links
|
|
100
|
+
subclass.cached = cached
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def reflected_record_type
|
|
104
|
+
return @reflected_record_type if defined?(@reflected_record_type)
|
|
105
|
+
|
|
106
|
+
@reflected_record_type ||= begin
|
|
107
|
+
if self.name.end_with?('Serializer')
|
|
108
|
+
self.name.split('::').last.chomp('Serializer').underscore.to_sym
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def set_key_transform(transform_name)
|
|
114
|
+
mapping = {
|
|
115
|
+
camel: :camelize,
|
|
116
|
+
camel_lower: [:camelize, :lower],
|
|
117
|
+
dash: :dasherize,
|
|
118
|
+
underscore: :underscore
|
|
119
|
+
}
|
|
120
|
+
self.transform_method = mapping[transform_name.to_sym]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def run_key_transform(input)
|
|
124
|
+
if self.transform_method.present?
|
|
125
|
+
input.to_s.send(*@transform_method).to_sym
|
|
126
|
+
else
|
|
127
|
+
input.to_sym
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def use_hyphen
|
|
132
|
+
warn('DEPRECATION WARNING: use_hyphen is deprecated and will be removed from fast_jsonapi 2.0 use (set_key_transform :dash) instead')
|
|
133
|
+
set_key_transform :dash
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def set_type(type_name)
|
|
137
|
+
self.record_type = run_key_transform(type_name)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def set_id(id_name)
|
|
141
|
+
self.record_id = id_name
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def cache_options(cache_options)
|
|
145
|
+
self.cached = cache_options[:enabled] || false
|
|
146
|
+
self.cache_length = cache_options[:cache_length] || 5.minutes
|
|
147
|
+
self.race_condition_ttl = cache_options[:race_condition_ttl] || 5.seconds
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def attributes(*attributes_list, &block)
|
|
151
|
+
attributes_list = attributes_list.first if attributes_list.first.class.is_a?(Array)
|
|
152
|
+
self.attributes_to_serialize = {} if self.attributes_to_serialize.nil?
|
|
153
|
+
attributes_list.each do |attr_name|
|
|
154
|
+
method_name = attr_name
|
|
155
|
+
key = run_key_transform(method_name)
|
|
156
|
+
attributes_to_serialize[key] = block || method_name
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
alias_method :attribute, :attributes
|
|
161
|
+
|
|
162
|
+
def add_relationship(name, relationship)
|
|
163
|
+
self.relationships_to_serialize = {} if relationships_to_serialize.nil?
|
|
164
|
+
self.cachable_relationships_to_serialize = {} if cachable_relationships_to_serialize.nil?
|
|
165
|
+
self.uncachable_relationships_to_serialize = {} if uncachable_relationships_to_serialize.nil?
|
|
166
|
+
|
|
167
|
+
if !relationship[:cached]
|
|
168
|
+
self.uncachable_relationships_to_serialize[name] = relationship
|
|
169
|
+
else
|
|
170
|
+
self.cachable_relationships_to_serialize[name] = relationship
|
|
171
|
+
end
|
|
172
|
+
self.relationships_to_serialize[name] = relationship
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def has_many(relationship_name, options = {}, &block)
|
|
176
|
+
name = relationship_name.to_sym
|
|
177
|
+
hash = create_relationship_hash(relationship_name, :has_many, options, block)
|
|
178
|
+
add_relationship(name, hash)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def has_one(relationship_name, options = {}, &block)
|
|
182
|
+
name = relationship_name.to_sym
|
|
183
|
+
hash = create_relationship_hash(relationship_name, :has_one, options, block)
|
|
184
|
+
add_relationship(name, hash)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def belongs_to(relationship_name, options = {}, &block)
|
|
188
|
+
name = relationship_name.to_sym
|
|
189
|
+
hash = create_relationship_hash(relationship_name, :belongs_to, options, block)
|
|
190
|
+
add_relationship(name, hash)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def create_relationship_hash(base_key, relationship_type, options, block)
|
|
194
|
+
name = base_key.to_sym
|
|
195
|
+
if relationship_type == :has_many
|
|
196
|
+
base_serialization_key = base_key.to_s.singularize
|
|
197
|
+
base_key_sym = base_serialization_key.to_sym
|
|
198
|
+
id_postfix = '_ids'
|
|
199
|
+
else
|
|
200
|
+
base_serialization_key = base_key
|
|
201
|
+
base_key_sym = name
|
|
202
|
+
id_postfix = '_id'
|
|
203
|
+
end
|
|
204
|
+
{
|
|
205
|
+
key: options[:key] || run_key_transform(base_key),
|
|
206
|
+
name: name,
|
|
207
|
+
id_method_name: options[:id_method_name] || "#{base_serialization_key}#{id_postfix}".to_sym,
|
|
208
|
+
record_type: options[:record_type] || run_key_transform(base_key_sym),
|
|
209
|
+
object_method_name: options[:object_method_name] || name,
|
|
210
|
+
object_block: block,
|
|
211
|
+
serializer: compute_serializer_name(options[:serializer] || base_key_sym),
|
|
212
|
+
relationship_type: relationship_type,
|
|
213
|
+
cached: options[:cached] || false,
|
|
214
|
+
polymorphic: fetch_polymorphic_option(options)
|
|
215
|
+
}
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def compute_serializer_name(serializer_key)
|
|
219
|
+
return serializer_key unless serializer_key.is_a? Symbol
|
|
220
|
+
namespace = self.name.gsub(/()?\w+Serializer$/, '')
|
|
221
|
+
serializer_name = serializer_key.to_s.classify + 'Serializer'
|
|
222
|
+
(namespace + serializer_name).to_sym
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def fetch_polymorphic_option(options)
|
|
226
|
+
option = options[:polymorphic]
|
|
227
|
+
return false unless option.present?
|
|
228
|
+
return option if option.respond_to? :keys
|
|
229
|
+
{}
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def link(link_name, link_method_name = nil, &block)
|
|
233
|
+
self.data_links = {} if self.data_links.nil?
|
|
234
|
+
link_method_name = link_name if link_method_name.nil?
|
|
235
|
+
key = run_key_transform(link_name)
|
|
236
|
+
self.data_links[key] = block || link_method_name
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def validate_includes!(includes)
|
|
240
|
+
return if includes.blank?
|
|
241
|
+
|
|
242
|
+
includes.detect do |include_item|
|
|
243
|
+
klass = self
|
|
244
|
+
parse_include_item(include_item).each do |parsed_include|
|
|
245
|
+
relationship_to_include = klass.relationships_to_serialize[parsed_include]
|
|
246
|
+
raise ArgumentError, "#{parsed_include} is not specified as a relationship on #{klass.name}" unless relationship_to_include
|
|
247
|
+
raise NotImplementedError if relationship_to_include[:polymorphic].is_a?(Hash)
|
|
248
|
+
klass = relationship_to_include[:serializer].to_s.constantize
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
require 'fast_jsonapi/multi_to_json'
|
|
5
|
+
|
|
6
|
+
module FastJsonapi
|
|
7
|
+
MandatoryField = Class.new(StandardError)
|
|
8
|
+
|
|
9
|
+
module SerializationCore
|
|
10
|
+
extend ActiveSupport::Concern
|
|
11
|
+
|
|
12
|
+
included do
|
|
13
|
+
class << self
|
|
14
|
+
attr_accessor :attributes_to_serialize,
|
|
15
|
+
:relationships_to_serialize,
|
|
16
|
+
:cachable_relationships_to_serialize,
|
|
17
|
+
:uncachable_relationships_to_serialize,
|
|
18
|
+
:transform_method,
|
|
19
|
+
:record_type,
|
|
20
|
+
:record_id,
|
|
21
|
+
:cache_length,
|
|
22
|
+
:race_condition_ttl,
|
|
23
|
+
:cached,
|
|
24
|
+
:data_links
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class_methods do
|
|
29
|
+
def id_hash(id, record_type, default_return=false)
|
|
30
|
+
if id.present?
|
|
31
|
+
{ id: id.to_s, type: record_type }
|
|
32
|
+
else
|
|
33
|
+
default_return ? { id: nil, type: record_type } : nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def ids_hash(ids, record_type)
|
|
38
|
+
return ids.map { |id| id_hash(id, record_type) } if ids.respond_to? :map
|
|
39
|
+
id_hash(ids, record_type) # ids variable is just a single id here
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def id_hash_from_record(record, record_types)
|
|
43
|
+
# memoize the record type within the record_types dictionary, then assigning to record_type:
|
|
44
|
+
record_type = record_types[record.class] ||= record.class.name.underscore.to_sym
|
|
45
|
+
id_hash(record.id, record_type)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def ids_hash_from_record_and_relationship(record, relationship, params = {})
|
|
49
|
+
polymorphic = relationship[:polymorphic]
|
|
50
|
+
|
|
51
|
+
return ids_hash(
|
|
52
|
+
fetch_id(record, relationship, params),
|
|
53
|
+
relationship[:record_type]
|
|
54
|
+
) unless polymorphic
|
|
55
|
+
|
|
56
|
+
return unless associated_object = fetch_associated_object(record, relationship, params)
|
|
57
|
+
|
|
58
|
+
return associated_object.map do |object|
|
|
59
|
+
id_hash_from_record object, polymorphic
|
|
60
|
+
end if associated_object.respond_to? :map
|
|
61
|
+
|
|
62
|
+
id_hash_from_record associated_object, polymorphic
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def links_hash(record, params = {})
|
|
66
|
+
data_links.each_with_object({}) do |(key, method), link_hash|
|
|
67
|
+
link_hash[key] = if method.is_a?(Proc)
|
|
68
|
+
method.arity == 1 ? method.call(record) : method.call(record, params)
|
|
69
|
+
else
|
|
70
|
+
record.public_send(method)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def attributes_hash(record, params = {})
|
|
76
|
+
attributes_to_serialize.each_with_object({}) do |(key, method), attr_hash|
|
|
77
|
+
attr_hash[key] = if method.is_a?(Proc)
|
|
78
|
+
method.arity == 1 ? method.call(record) : method.call(record, params)
|
|
79
|
+
else
|
|
80
|
+
record.public_send(method)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def relationships_hash(record, relationships = nil, params = {})
|
|
86
|
+
relationships = relationships_to_serialize if relationships.nil?
|
|
87
|
+
|
|
88
|
+
relationships.each_with_object({}) do |(_k, relationship), hash|
|
|
89
|
+
name = relationship[:key]
|
|
90
|
+
empty_case = relationship[:relationship_type] == :has_many ? [] : nil
|
|
91
|
+
hash[name] = {
|
|
92
|
+
data: ids_hash_from_record_and_relationship(record, relationship, params) || empty_case
|
|
93
|
+
}
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def record_hash(record, params = {})
|
|
98
|
+
if cached
|
|
99
|
+
record_hash = Rails.cache.fetch(record.cache_key, expires_in: cache_length, race_condition_ttl: race_condition_ttl) do
|
|
100
|
+
temp_hash = id_hash(id_from_record(record), record_type, true)
|
|
101
|
+
temp_hash[:attributes] = attributes_hash(record, params) if attributes_to_serialize.present?
|
|
102
|
+
temp_hash[:relationships] = {}
|
|
103
|
+
temp_hash[:relationships] = relationships_hash(record, cachable_relationships_to_serialize, params) if cachable_relationships_to_serialize.present?
|
|
104
|
+
temp_hash[:links] = links_hash(record, params) if data_links.present?
|
|
105
|
+
temp_hash
|
|
106
|
+
end
|
|
107
|
+
record_hash[:relationships] = record_hash[:relationships].merge(relationships_hash(record, uncachable_relationships_to_serialize, params)) if uncachable_relationships_to_serialize.present?
|
|
108
|
+
record_hash
|
|
109
|
+
else
|
|
110
|
+
record_hash = id_hash(id_from_record(record), record_type, true)
|
|
111
|
+
record_hash[:attributes] = attributes_hash(record, params) if attributes_to_serialize.present?
|
|
112
|
+
record_hash[:relationships] = relationships_hash(record, nil, params) if relationships_to_serialize.present?
|
|
113
|
+
record_hash[:links] = links_hash(record, params) if data_links.present?
|
|
114
|
+
record_hash
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def id_from_record(record)
|
|
119
|
+
return record.send(record_id) if record_id
|
|
120
|
+
raise MandatoryField, 'id is a mandatory field in the jsonapi spec' unless record.respond_to?(:id)
|
|
121
|
+
record.id
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Override #to_json for alternative implementation
|
|
125
|
+
def to_json(payload)
|
|
126
|
+
FastJsonapi::MultiToJson.to_json(payload) if payload.present?
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def parse_include_item(include_item)
|
|
130
|
+
return [include_item.to_sym] unless include_item.to_s.include?('.')
|
|
131
|
+
include_item.to_s.split('.').map { |item| item.to_sym }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def remaining_items(items)
|
|
135
|
+
return unless items.size > 1
|
|
136
|
+
|
|
137
|
+
items_copy = items.dup
|
|
138
|
+
items_copy.delete_at(0)
|
|
139
|
+
[items_copy.join('.').to_sym]
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# includes handler
|
|
143
|
+
def get_included_records(record, includes_list, known_included_objects, params = {})
|
|
144
|
+
return unless includes_list.present?
|
|
145
|
+
|
|
146
|
+
includes_list.sort.each_with_object([]) do |include_item, included_records|
|
|
147
|
+
items = parse_include_item(include_item)
|
|
148
|
+
items.each do |item|
|
|
149
|
+
next unless relationships_to_serialize && relationships_to_serialize[item]
|
|
150
|
+
raise NotImplementedError if @relationships_to_serialize[item][:polymorphic].is_a?(Hash)
|
|
151
|
+
record_type = @relationships_to_serialize[item][:record_type]
|
|
152
|
+
serializer = @relationships_to_serialize[item][:serializer].to_s.constantize
|
|
153
|
+
relationship_type = @relationships_to_serialize[item][:relationship_type]
|
|
154
|
+
|
|
155
|
+
included_objects = fetch_associated_object(record, @relationships_to_serialize[item], params)
|
|
156
|
+
next if included_objects.blank?
|
|
157
|
+
included_objects = [included_objects] unless relationship_type == :has_many
|
|
158
|
+
|
|
159
|
+
included_objects.each do |inc_obj|
|
|
160
|
+
if remaining_items(items)
|
|
161
|
+
serializer_records = serializer.get_included_records(inc_obj, remaining_items(items), known_included_objects)
|
|
162
|
+
included_records.concat(serializer_records) unless serializer_records.empty?
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
code = "#{record_type}_#{inc_obj.id}"
|
|
166
|
+
next if known_included_objects.key?(code)
|
|
167
|
+
|
|
168
|
+
known_included_objects[code] = inc_obj
|
|
169
|
+
included_records << serializer.record_hash(inc_obj, params)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def fetch_associated_object(record, relationship, params)
|
|
176
|
+
return relationship[:object_block].call(record, params) unless relationship[:object_block].nil?
|
|
177
|
+
record.send(relationship[:object_method_name])
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def fetch_id(record, relationship, params)
|
|
181
|
+
unless relationship[:object_block].nil?
|
|
182
|
+
object = relationship[:object_block].call(record, params)
|
|
183
|
+
|
|
184
|
+
return object.map(&:id) if object.respond_to? :map
|
|
185
|
+
return object.id
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
record.public_send(relationship[:id_method_name])
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
@@ -3,6 +3,8 @@ module Lp
|
|
|
3
3
|
module Utilities
|
|
4
4
|
private
|
|
5
5
|
|
|
6
|
+
REDUNDANT_KEYS = %i(attributes relationships)
|
|
7
|
+
|
|
6
8
|
def nest_data?(resource, nested)
|
|
7
9
|
if nested
|
|
8
10
|
resource
|
|
@@ -34,15 +36,26 @@ module Lp
|
|
|
34
36
|
def flatten_hash(hash)
|
|
35
37
|
return unless hash
|
|
36
38
|
hash.each_with_object({}) do |(k, v), h|
|
|
37
|
-
if
|
|
39
|
+
if hash_and_matches_redundant_keys?(v, k)
|
|
38
40
|
flatten_hash(v).map do |h_k, h_v|
|
|
39
|
-
h[
|
|
41
|
+
h[h_k.to_s.to_sym] = h_v
|
|
40
42
|
end
|
|
41
|
-
|
|
43
|
+
# NOTE: extract this into a different method?
|
|
44
|
+
elsif hash_and_has_data_key?(v)
|
|
45
|
+
h[k] = expose_data(v)
|
|
46
|
+
else
|
|
42
47
|
h[k] = v
|
|
43
48
|
end
|
|
44
49
|
end
|
|
45
50
|
end
|
|
51
|
+
|
|
52
|
+
def hash_and_has_data_key?(value)
|
|
53
|
+
value.is_a?(Hash) && value.key?(:data)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def hash_and_matches_redundant_keys?(value, key)
|
|
57
|
+
value.is_a?(Hash) && REDUNDANT_KEYS.any?{|sym| sym == key}
|
|
58
|
+
end
|
|
46
59
|
end
|
|
47
60
|
end
|
|
48
61
|
end
|
data/lib/lp/serializable.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require "lp/serializable/version"
|
|
2
1
|
require "lp/serializable/strategies"
|
|
3
2
|
|
|
4
3
|
module Lp
|
|
@@ -19,13 +18,15 @@ module Lp
|
|
|
19
18
|
def serialize_and_flatten_with_class_name(resource, class_name, options={})
|
|
20
19
|
raise UnserializableCollection if resource.is_a?(Array)
|
|
21
20
|
base_hash = serializable_hash_with_class_name(resource,
|
|
22
|
-
|
|
21
|
+
class_name,
|
|
22
|
+
options)
|
|
23
23
|
flatten_and_nest_data(base_hash, set_nested_option(options))
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def serialize_and_flatten_collection(resource, class_name, options={})
|
|
27
27
|
base_hash = serializable_hash_with_class_name(resource,
|
|
28
|
-
|
|
28
|
+
class_name,
|
|
29
|
+
options)
|
|
29
30
|
flatten_array_and_nest_data(base_hash, set_nested_option(options))
|
|
30
31
|
end
|
|
31
32
|
end
|
data/lp-serializable.gemspec
CHANGED
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.email = ["nate@mrjones.io"]
|
|
11
11
|
|
|
12
12
|
spec.summary = "Serialize with Fast JSON API, flatten like AWS"
|
|
13
|
-
|
|
13
|
+
spec.description = "JSON API(jsonapi.org) serializer wrapper methods that work with Rails and can be used to serialize any kind of ruby object with AMS style output."
|
|
14
14
|
spec.homepage = "https://www.github.com/launchpadlab/lp-serializable"
|
|
15
15
|
spec.license = "MIT"
|
|
16
16
|
|
|
@@ -35,6 +35,15 @@ Gem::Specification.new do |spec|
|
|
|
35
35
|
spec.add_development_dependency "rake", "~> 10.0"
|
|
36
36
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
37
37
|
spec.add_development_dependency "pry"
|
|
38
|
+
spec.add_development_dependency(%q<activerecord>, [">= 4.2"])
|
|
39
|
+
spec.add_development_dependency(%q<active_model_serializers>, ["~> 0.10.7"])
|
|
40
|
+
spec.add_development_dependency(%q<jsonapi-rb>, ["~> 0.5.0"])
|
|
41
|
+
spec.add_development_dependency(%q<sqlite3>, ["~> 1.3"])
|
|
42
|
+
spec.add_development_dependency(%q<jsonapi-serializers>, ["~> 1.0.0"])
|
|
43
|
+
spec.add_development_dependency(%q<oj>, ["~> 3.3"])
|
|
44
|
+
spec.add_development_dependency(%q<rspec-benchmark>, ["~> 0.3.0"])
|
|
45
|
+
spec.add_runtime_dependency(%q<activesupport>, [">= 4.2"])
|
|
46
|
+
spec.add_development_dependency(%q<byebug>, [">= 0"])
|
|
38
47
|
|
|
39
|
-
spec.add_dependency "fast_jsonapi"
|
|
40
|
-
end
|
|
48
|
+
spec.add_dependency "fast_jsonapi", '>= 1.2'
|
|
49
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lp-serializable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mrjonesbot
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-07-
|
|
11
|
+
date: 2018-07-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: appraisal
|
|
@@ -81,20 +81,147 @@ dependencies:
|
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: activerecord
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - ">="
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
89
|
+
version: '4.2'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '4.2'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: active_model_serializers
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 0.10.7
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 0.10.7
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: jsonapi-rb
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: 0.5.0
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: 0.5.0
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: sqlite3
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '1.3'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '1.3'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: jsonapi-serializers
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: 1.0.0
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: 1.0.0
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: oj
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '3.3'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '3.3'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: rspec-benchmark
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - "~>"
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: 0.3.0
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - "~>"
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: 0.3.0
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: activesupport
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - ">="
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '4.2'
|
|
90
188
|
type: :runtime
|
|
91
189
|
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - ">="
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '4.2'
|
|
195
|
+
- !ruby/object:Gem::Dependency
|
|
196
|
+
name: byebug
|
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
|
198
|
+
requirements:
|
|
199
|
+
- - ">="
|
|
200
|
+
- !ruby/object:Gem::Version
|
|
201
|
+
version: '0'
|
|
202
|
+
type: :development
|
|
203
|
+
prerelease: false
|
|
92
204
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
205
|
requirements:
|
|
94
206
|
- - ">="
|
|
95
207
|
- !ruby/object:Gem::Version
|
|
96
208
|
version: '0'
|
|
97
|
-
|
|
209
|
+
- !ruby/object:Gem::Dependency
|
|
210
|
+
name: fast_jsonapi
|
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
|
212
|
+
requirements:
|
|
213
|
+
- - ">="
|
|
214
|
+
- !ruby/object:Gem::Version
|
|
215
|
+
version: '1.2'
|
|
216
|
+
type: :runtime
|
|
217
|
+
prerelease: false
|
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
219
|
+
requirements:
|
|
220
|
+
- - ">="
|
|
221
|
+
- !ruby/object:Gem::Version
|
|
222
|
+
version: '1.2'
|
|
223
|
+
description: JSON API(jsonapi.org) serializer wrapper methods that work with Rails
|
|
224
|
+
and can be used to serialize any kind of ruby object with AMS style output.
|
|
98
225
|
email:
|
|
99
226
|
- nate@mrjones.io
|
|
100
227
|
executables: []
|
|
@@ -103,6 +230,7 @@ extra_rdoc_files: []
|
|
|
103
230
|
files:
|
|
104
231
|
- ".gitignore"
|
|
105
232
|
- ".rspec"
|
|
233
|
+
- ".ruby-version"
|
|
106
234
|
- ".travis.yml"
|
|
107
235
|
- CODE_OF_CONDUCT.md
|
|
108
236
|
- Gemfile
|
|
@@ -112,6 +240,9 @@ files:
|
|
|
112
240
|
- Rakefile
|
|
113
241
|
- bin/console
|
|
114
242
|
- bin/setup
|
|
243
|
+
- lib/fast_jsonapi/multi_to_json.rb
|
|
244
|
+
- lib/fast_jsonapi/object_serializer.rb
|
|
245
|
+
- lib/fast_jsonapi/serialization_core.rb
|
|
115
246
|
- lib/lp/serializable.rb
|
|
116
247
|
- lib/lp/serializable/strategies.rb
|
|
117
248
|
- lib/lp/serializable/utilities.rb
|