jsonapi-realizer 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f3e9f32f5798910d492d81a0564ff99337b65577d7f0fff93cc1b627c53e0bd2
4
+ data.tar.gz: 754cf56ffe68f405a1b68ee3d2ebb2da4d8b89146f6048e6e5c4d9755b72ff93
5
+ SHA512:
6
+ metadata.gz: '076844edcdb11676eb825d8707c331fc00736cf5c31e2b345fb134cb28363315ee317d046830aa4d654741560a66ad5a2caef71cd224b12c372b427d9517cf26'
7
+ data.tar.gz: 6216f9f0c53cf4b27f25f4c90e768092525e477de0156d9fbbdd09d4e952513a3f73b8247b803d9325a3883f6f2d07a1a8b846a2986c6c9de839210c6de37cab
data/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # jsonapi-realizer
2
+
3
+ - [![Build](http://img.shields.io/travis-ci/krainboltgreene/jsonapi-realizer.svg?style=flat-square)](https://travis-ci.org/krainboltgreene/jsonapi-realizer)
4
+ - [![Downloads](http://img.shields.io/gem/dtv/jsonapi-realizer.svg?style=flat-square)](https://rubygems.org/gems/jsonapi-realizer)
5
+ - [![Version](http://img.shields.io/gem/v/jsonapi-realizer.svg?style=flat-square)](https://rubygems.org/gems/jsonapi-realizer)
6
+
7
+
8
+ This library handles incoming [json:api](https://www.jsonapi.org) payloads and turns them, via an adapter system, into data models for your business logic.
9
+
10
+ A successful JSON:API request can be annotated as:
11
+
12
+ ```
13
+ JSONAPIRequest -> (PersistanceAdapter -> JSONAPIRequest -> (Record | Array<Record>)) -> JSONAPIResponse
14
+ ```
15
+
16
+ The `jsonapi-serializers` library provides this shape:
17
+
18
+ ```
19
+ JSONAPIRequest -> (Record | Array<Record>) -> JSONAPIResponse
20
+ ```
21
+
22
+ But it leaves fetching/createing/updating/destroying the records up to you! This is where jsonapi-realizer comes into play, as it provides this shape:
23
+
24
+ ```
25
+ PersistanceAdapter -> JSONAPIRequest -> (Record | Array<Record>)
26
+ ```
27
+
28
+
29
+ ## Using
30
+
31
+ ``` ruby
32
+ class Photo < ApplicationRecord
33
+ belongs_to :photographer, class_name: "Profile"
34
+ end
35
+
36
+ class Profile < ApplicationRecord
37
+ has_many :photos
38
+ end
39
+
40
+ class PhotoRealizer
41
+ include JSONAPI::Realizer::Resource
42
+
43
+ adapter :active_record
44
+
45
+ represents :photos, class_name: "Photo"
46
+
47
+ has_one :photographer, as: :profiles
48
+
49
+ has :title
50
+ has :src
51
+ end
52
+
53
+ class ProfileRealizer
54
+ include JSONAPI::Realizer::Resource
55
+
56
+ adapter :active_record
57
+
58
+ represents :profiles, class_name: "Profile"
59
+
60
+ has_many :photos, as: :photos
61
+
62
+ has :name
63
+ end
64
+ ```
65
+
66
+ Once you've designed your resources, we just need to use them! In this example, we'll use controllers from Rails:
67
+
68
+ ``` ruby
69
+ class PhotosController < ApplicationController
70
+ def create
71
+ validate_parameters!
72
+ authenticate_session!
73
+
74
+ record = JSONAPI::Realizer.create(params, headers: request.headers)
75
+
76
+ ProcessPhotosService.new(record)
77
+
78
+ JSONAPI::Serializer.serialize(record)
79
+ end
80
+ end
81
+ ```
82
+
83
+ ### Adapters
84
+
85
+ There are two core adapters:
86
+
87
+ 0. `:active_record`, which assumes an ActiveRecord-like interface.
88
+ 0. `:memory`, which assumes a `STORE` Hash-like on the model class.
89
+
90
+ An adapter must provide the following interfaces:
91
+
92
+ 0. `find_via`, which tells the action how to find the model
93
+ 0. `write_attributes_via`, which tells the action how to write an individual property
94
+ 0. `save_via`, which tells the action how to save the model when it's done
95
+
96
+ You can also provide custom adapter interfaces:
97
+
98
+ ``` ruby
99
+ class PhotoRealizer
100
+ include JSONAPI::Realizer::Resource
101
+
102
+ adapter do
103
+ find_via do |model_class, id|
104
+ model_class.where { id == id or slug == id }.first
105
+ end
106
+
107
+ write_attributes_via do |model, attributes|
108
+ model.update_columns(attributes)
109
+ end
110
+
111
+ save_via do |model|
112
+ model.save!
113
+ Rails.cache.write(model.cache_key, model)
114
+ end
115
+ end
116
+
117
+ represents :photos, class_name: "Photo"
118
+
119
+ has_one :photographer, as: :profiles
120
+
121
+ has :title
122
+ has :src
123
+ end
124
+ ```
125
+
126
+ If you want, you can use both the regular adapters and some custom pieces:
127
+
128
+ ``` ruby
129
+ class PhotoRealizer
130
+ include JSONAPI::Realizer::Resource
131
+
132
+ adapter :active_record do
133
+ find_via do |model_class, id|
134
+ model_class.where { id == id or slug == id }.first
135
+ end
136
+ end
137
+
138
+ represents :photos, class_name: "Photo"
139
+
140
+ has_one :photographer, as: :profiles
141
+
142
+ has :title
143
+ has :src
144
+ end
145
+ ```
146
+
147
+ ## Installing
148
+
149
+ Add this line to your application's Gemfile:
150
+
151
+ gem "jsonapi-realizer", "1.0.0"
152
+
153
+ And then execute:
154
+
155
+ $ bundle
156
+
157
+ Or install it yourself with:
158
+
159
+ $ gem install jsonapi-realizer
160
+
161
+
162
+ ## Contributing
163
+
164
+ 1. Read the [Code of Conduct](/CONDUCT.md)
165
+ 2. Fork it
166
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
167
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
168
+ 5. Push to the branch (`git push origin my-new-feature`)
169
+ 6. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ desc "Run all the tests in spec"
7
+ RSpec::Core::RakeTask.new(:spec) do |let|
8
+ let.pattern = "lib/**{,/*/**}/*_spec.rb"
9
+ end
10
+
11
+ desc "Default: run tests"
12
+ task default: :spec
@@ -0,0 +1,3 @@
1
+ module JSONAPI
2
+ require_relative "jsonapi/realizer"
3
+ end
@@ -0,0 +1,30 @@
1
+ require "ostruct"
2
+ require "active_support/concern"
3
+
4
+ module JSONAPI
5
+ module Realizer
6
+ require_relative "realizer/version"
7
+ require_relative "realizer/action"
8
+ require_relative "realizer/adapter"
9
+ require_relative "realizer/resource"
10
+
11
+ def self.register(resource_class, model_class, type)
12
+ @mapping ||= {}
13
+ @mapping[type] = OpenStruct.new({
14
+ model_class: model_class,
15
+ type: type,
16
+ resource_class: resource_class,
17
+ attributes: OpenStruct.new({}),
18
+ relationships: OpenStruct.new({})
19
+ })
20
+ end
21
+
22
+ def self.mapping
23
+ @mapping
24
+ end
25
+
26
+ def self.create(payload, headers:)
27
+ Create.new(payload: payload, headers: headers).call
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ class Action
4
+ require_relative "action/create"
5
+ require_relative "action/update"
6
+
7
+ attr_reader :type
8
+ attr_reader :data
9
+ attr_reader :resource
10
+
11
+ def initialize(payload:, headers:)
12
+ raise NoMethodError, "must implement this function"
13
+ end
14
+
15
+ def call
16
+ raise NoMethodError, "must implement this function"
17
+ end
18
+
19
+ private def resource_class
20
+ JSONAPI::Realizer.mapping.fetch(type).resource_class
21
+ end
22
+
23
+ private def relationships
24
+ data.fetch("relationships", {})
25
+ end
26
+
27
+ private def id
28
+ data.fetch("id", nil)
29
+ end
30
+
31
+ private def type
32
+ data.fetch("type")
33
+ end
34
+
35
+ private def attributes
36
+ data.fetch("attributes", {})
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ class Action
4
+ class Create < Action
5
+ def initialize(payload:, headers:)
6
+ @data = payload.fetch("data")
7
+ @resource = resource_class.new(resource_class.model_class.new)
8
+ end
9
+
10
+ def call
11
+ resource.model.tap do |model|
12
+ resource_class.write_attributes_via_call(model, {id: id}) if id
13
+ resource_class.write_attributes_via_call(model, attributes.select(&resource.method(:valid_attribute?)))
14
+ resource_class.write_attributes_via_call(model, relationships.select(&resource.method(:valid_relationship?)).transform_values(&resource.method(:as_relationship)))
15
+ resource_class.save_via_call(model)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe JSONAPI::Realizer::Action::Create do
4
+ let(:action) { described_class.new(payload: payload, headers: headers) }
5
+
6
+ describe "#call" do
7
+ subject { action.call }
8
+
9
+ context "with a good payload and good headers" do
10
+ let(:payload) do
11
+ {
12
+ "data" => {
13
+ "id" => "550e8400-e29b-41d4-a716-446655440000",
14
+ "type" => "photos",
15
+ "attributes" => {
16
+ "title" => "Ember Hamster",
17
+ "src" => "http://example.com/images/productivity.png"
18
+ },
19
+ "relationships" => {
20
+ "photographer" => {
21
+ "data" => { "type" => "people", "id" => "4b8a0af6-953d-4729-8b9a-1fa4eb18f3c9" }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ end
27
+ let(:headers) do
28
+ {
29
+ "Content-Type" => "application/vnd.api+json",
30
+ "Accept" => "application/vnd.api+json"
31
+ }
32
+ end
33
+
34
+ before do
35
+ People::STORE["4b8a0af6-953d-4729-8b9a-1fa4eb18f3c9"] = {
36
+ id: "4b8a0af6-953d-4729-8b9a-1fa4eb18f3c9",
37
+ name: "Kurtis Rainbolt-Greene"
38
+ }
39
+ end
40
+
41
+ it "creates a model" do
42
+ expect(subject).to be_a_kind_of(Photo)
43
+ end
44
+
45
+ it "assigns the attributes" do
46
+ expect(subject).to have_attributes(title: "Ember Hamster", src: "http://example.com/images/productivity.png", updated_at: a_kind_of(Time))
47
+ end
48
+
49
+ it "relates the relationships" do
50
+ expect(subject).to have_attributes(photographer: a_kind_of(People))
51
+ end
52
+
53
+ it "stores the new record" do
54
+ expect {subject}.to change {Photo::STORE}.from({}).to({"550e8400-e29b-41d4-a716-446655440000" => hash_including(id: "550e8400-e29b-41d4-a716-446655440000", title: "Ember Hamster", src: "http://example.com/images/productivity.png")})
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,25 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ class Action
4
+ class Update < Action
5
+ def initialize(payload:, headers:)
6
+ @data = payload.fetch("data")
7
+ @resource = resource_class.new(
8
+ resource_class.find_via_call(
9
+ resource_class.model_class,
10
+ id
11
+ )
12
+ )
13
+ end
14
+
15
+ def call
16
+ @resource.model.tap do |model|
17
+ resource_class.write_attributes_via_call(model, attributes.select(&resource.method(:valid_attribute?)))
18
+ resource_class.write_attributes_via_call(model, relationships.select(&resource.method(:valid_relationship?)).transform_values(&resource.method(:as_relationship)))
19
+ resource_class.save_via_call(model)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,63 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe JSONAPI::Realizer::Action::Update do
4
+ let(:action) { described_class.new(payload: payload, headers: headers) }
5
+
6
+ describe "#call" do
7
+ subject { action.call }
8
+
9
+ context "with a good payload and good headers" do
10
+ let(:payload) do
11
+ {
12
+ "data" => {
13
+ "id" => "550e8400-e29b-41d4-a716-446655440000",
14
+ "type" => "photos",
15
+ "attributes" => {
16
+ "title" => "Ember Hamster 2",
17
+ "src" => "http://example.com/images/productivity-2.png"
18
+ },
19
+ "relationships" => {
20
+ "photographer" => {
21
+ "data" => { "type" => "people", "id" => "4b8a0af6-953d-4729-8b9a-1fa4eb18f3c9" }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ end
27
+ let(:headers) do
28
+ {
29
+ "Content-Type" => "application/vnd.api+json",
30
+ "Accept" => "application/vnd.api+json"
31
+ }
32
+ end
33
+
34
+ before do
35
+ People::STORE["4b8a0af6-953d-4729-8b9a-1fa4eb18f3c9"] = {
36
+ id: "4b8a0af6-953d-4729-8b9a-1fa4eb18f3c9",
37
+ name: "Kurtis Rainbolt-Greene"
38
+ }
39
+ Photo::STORE["550e8400-e29b-41d4-a716-446655440000"] = {
40
+ id: "550e8400-e29b-41d4-a716-446655440000",
41
+ title: "Ember Hamster",
42
+ src: "http://example.com/images/productivity.png"
43
+ }
44
+ end
45
+
46
+ it "creates a model" do
47
+ expect(subject).to be_a_kind_of(Photo)
48
+ end
49
+
50
+ it "assigns the attributes" do
51
+ expect(subject).to have_attributes(title: "Ember Hamster 2", src: "http://example.com/images/productivity-2.png", updated_at: a_kind_of(Time))
52
+ end
53
+
54
+ it "relates the relationships" do
55
+ expect(subject).to have_attributes(photographer: a_kind_of(People))
56
+ end
57
+
58
+ it "saves the record" do
59
+ expect {subject}.to change {Photo::STORE}.from({"550e8400-e29b-41d4-a716-446655440000" => hash_including(id: "550e8400-e29b-41d4-a716-446655440000", title: "Ember Hamster", src: "http://example.com/images/productivity.png")}).to({"550e8400-e29b-41d4-a716-446655440000" => hash_including(id: "550e8400-e29b-41d4-a716-446655440000", title: "Ember Hamster 2", src: "http://example.com/images/productivity-2.png")})
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,33 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ module Adapter
4
+ require_relative "adapter/active_record"
5
+ require_relative "adapter/memory"
6
+
7
+ MAPPINGS = {
8
+ memory: JSONAPI::Realizer::Adapter::Memory,
9
+ active_record: JSONAPI::Realizer::Adapter::ActiveRecord,
10
+ }
11
+
12
+ def self.adapt(resource, interface, &block)
13
+ if interface.kind_of?(Symbol)
14
+ if JSONAPI::Realizer::Adapter::MAPPINGS.key?(interface)
15
+ resource.include(JSONAPI::Realizer::Adapter::MAPPINGS.fetch(interface))
16
+ else
17
+ raise ArgumentError, "you've given an invalid adapter alias: #{interface}, we support #{JSONAPI::Realizer::Adapter::MAPPINGS.keys}"
18
+ end
19
+ else
20
+ resource.include(interface)
21
+ end
22
+
23
+ if block_given?
24
+ resource.instance_eval(&block)
25
+ end
26
+
27
+ raise ArgumentError, "need to provide a Adapter.find_via interface" unless resource.instance_variable_defined?(:@find_via_call)
28
+ raise ArgumentError, "need to provide a Adapter.write_attributes_via interface" unless resource.instance_variable_defined?(:@write_attributes_via_call)
29
+ raise ArgumentError, "need to provide a Adapter.save_via interface" unless resource.instance_variable_defined?(:@save_via_call)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ module Adapter
4
+ module ActiveRecord
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ find_via do |model_class, id|
9
+ model_class.find(id)
10
+ end
11
+
12
+ write_attributes_via do |model, attributes|
13
+ model.assign_attributes(attributes)
14
+ end
15
+
16
+ save_via do |model|
17
+ model.save!
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ module Adapter
4
+ module Memory
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ find_via do |model_class, id|
9
+ model_class.fetch(id)
10
+ end
11
+
12
+ write_attributes_via do |model, attributes|
13
+ model.assign_attributes(attributes)
14
+ end
15
+
16
+ save_via do |model|
17
+ model.assign_attributes(id: model.id || SecureRandom.uuid)
18
+ model.assign_attributes(updated_at: Time.now)
19
+ model_class.const_get("STORE")[model.id] = model_class.const_get("ATTRIBUTES").inject({}) do |hash, key|
20
+ hash.merge({ key => model.public_send(key) })
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe JSONAPI::Realizer::Adapter do
4
+ describe ".adapt" do
5
+ context "for the active_record mapped alias" do
6
+ it "defines the find_via_call instance variable as a anonymous function"
7
+ it "defines the find_via_call instance variable as a anonymous function"
8
+ end
9
+
10
+ context "for a mapped alias that doesn't exist" do
11
+
12
+ end
13
+
14
+ context "for a block defintion" do
15
+
16
+ end
17
+
18
+ context "for an alias and block defintion" do
19
+
20
+ end
21
+
22
+ context "when the find_via interface isn't defined" do
23
+
24
+ end
25
+
26
+ context "when the write_attributes_via interface isn't defined" do
27
+
28
+ end
29
+
30
+ context "when the save_via interface isn't defined" do
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,122 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ class Resource
4
+ extend ActiveSupport::Concern
5
+
6
+ attr_reader :model
7
+
8
+ def initialize(model)
9
+ @model = model
10
+ end
11
+
12
+ def relationship(name)
13
+ relationships.public_send(name.to_sym)
14
+ end
15
+
16
+ def attribute(name)
17
+ relationships.public_send(name.to_sym)
18
+ end
19
+
20
+ private def attributes
21
+ configuration.attributes
22
+ end
23
+
24
+ private def relationships
25
+ configuration.relationships
26
+ end
27
+
28
+ private def as_relationship(value)
29
+ data = value.fetch("data")
30
+ mapping = JSONAPI::Realizer.mapping.fetch(data.fetch("type"))
31
+ mapping.resource_class.find_via_call(
32
+ mapping.model_class,
33
+ data.fetch("id")
34
+ )
35
+ end
36
+
37
+ private def model_class
38
+ configuration.model_class
39
+ end
40
+
41
+ private def configuration
42
+ self.class.configuration
43
+ end
44
+
45
+ def valid_attribute?(name, value)
46
+ attributes.respond_to?(name.to_sym)
47
+ end
48
+
49
+ def valid_relationship?(name, value)
50
+ relationships.respond_to?(name.to_sym)
51
+ end
52
+
53
+ def self.represents(type, class_name:)
54
+ @configuration = JSONAPI::Realizer.register(self, class_name.constantize, type.to_s)
55
+ end
56
+
57
+ def self.adapter(interface, &block)
58
+ JSONAPI::Realizer::Adapter.adapt(self, interface, &block)
59
+ end
60
+
61
+ def self.find_via(&finder)
62
+ @find_via_call = finder
63
+ end
64
+
65
+ def self.find_via_call(model_class, id)
66
+ @find_via_call.call(model_class, id)
67
+ end
68
+
69
+ def self.save_via(&saver)
70
+ @save_via_call = saver
71
+ end
72
+
73
+ def self.save_via_call(model)
74
+ @save_via_call.call(model)
75
+ end
76
+
77
+ def self.write_attributes_via(&writer)
78
+ @write_attributes_via_call = writer
79
+ end
80
+
81
+ def self.write_attributes_via_call(model, attributes)
82
+ @write_attributes_via_call.call(model, attributes)
83
+ end
84
+
85
+ def self.has_one(name, as: name)
86
+ relationships.public_send("#{name}=", OpenStruct.new({name: name, as: as}))
87
+ end
88
+
89
+ def self.has(name)
90
+ attributes.public_send("#{name}=", OpenStruct.new({name: name}))
91
+ end
92
+
93
+ def self.relationship(name)
94
+ relationships.public_send(name.to_sym)
95
+ end
96
+
97
+ def self.attribute(name)
98
+ relationships.public_send(name.to_sym)
99
+ end
100
+
101
+ def self.attributes
102
+ configuration.attributes
103
+ end
104
+
105
+ def self.relationships
106
+ configuration.relationships
107
+ end
108
+
109
+ def self.model_class
110
+ configuration.model_class
111
+ end
112
+
113
+ def self.configuration
114
+ if @configuration
115
+ @configuration
116
+ else
117
+ raise ArgumentError, "you need to have the resource configured"
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,5 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe JSONAPI::Realizer::VERSION do
4
+ it "should be a string" do
5
+ expect(JSONAPI::Realizer::VERSION).to be_kind_of(String)
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe JSONAPI::Realizer do
4
+ it "on create generates a model with a relationship and a client id" do
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jsonapi-realizer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Kurtis Rainbolt-Greene
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-03-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '12.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '12.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activemodel
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-doc
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.11'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.11'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '5.1'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '5.1'
111
+ description: A way to take json:api requests and turn them into models
112
+ email:
113
+ - kurtis@rainbolt-greene.online
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - README.md
119
+ - Rakefile
120
+ - lib/jsonapi-realizer.rb
121
+ - lib/jsonapi/realizer.rb
122
+ - lib/jsonapi/realizer/action.rb
123
+ - lib/jsonapi/realizer/action/create.rb
124
+ - lib/jsonapi/realizer/action/create_spec.rb
125
+ - lib/jsonapi/realizer/action/update.rb
126
+ - lib/jsonapi/realizer/action/update_spec.rb
127
+ - lib/jsonapi/realizer/adapter.rb
128
+ - lib/jsonapi/realizer/adapter/active_record.rb
129
+ - lib/jsonapi/realizer/adapter/memory.rb
130
+ - lib/jsonapi/realizer/adapter_spec.rb
131
+ - lib/jsonapi/realizer/resource.rb
132
+ - lib/jsonapi/realizer/version.rb
133
+ - lib/jsonapi/realizer/version_spec.rb
134
+ - lib/jsonapi/realizer_spec.rb
135
+ homepage: http://krainboltgreene.github.io/jsonapi-realizer
136
+ licenses:
137
+ - ISC
138
+ metadata: {}
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 2.7.4
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: A way to take json:api requests and turn them into models
159
+ test_files: []