active_record-remote 0.0.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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +2 -0
- data/active_record-remote.gemspec +28 -0
- data/lib/active_record/remote.rb +9 -0
- data/lib/active_record/remote/base.rb +112 -0
- data/lib/active_record/remote/client.rb +70 -0
- data/lib/active_record/remote/core_ext/hash.rb +40 -0
- data/lib/active_record/remote/helpers/association_helper.rb +56 -0
- data/lib/active_record/remote/helpers/request_helper.rb +19 -0
- data/lib/active_record/remote/helpers/serialization_helper.rb +53 -0
- data/lib/active_record/remote/helpers/soap_helper.rb +19 -0
- data/lib/active_record/remote/helpers/xml_helper.rb +19 -0
- data/lib/active_record/remote/response.rb +40 -0
- data/lib/active_record/remote/version.rb +5 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d72e68a69e314e8e66a694f12fe52dd5a46c16d1
|
4
|
+
data.tar.gz: d4c80560035c03ad31a25f7ff4fe730558bb364c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 467fe7bd459140a835db5cbfa3309e24e684198cf82891f9ca6729c4a83d15ccde8acce9007aad57a724f328c9cbf15b2b38eaa8c295d52acdde45e8c90f84bd
|
7
|
+
data.tar.gz: 312a3f2a0ffb0771820d952bf3b5f275df9743c459c65f4a3d3b2904c726769cab55b1eb369b83e4ba6f9d2a545d3606376804727e9da98db06424a0d09b90cb
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Justin Grubbs
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# ActiveRecord::Remote
|
2
|
+
|
3
|
+
This gem is a work in progress. The goal is to create a library that allows Ruby wrappers to be agnostic of the communication method. SOAP, XML, JSON, and Flat File all can be written in a similar format. To see a working example for a SOAP API [jGRUBBS/rlm_logistics](https://github.com/jGRUBBS/rlm_logistics).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'active_record-remote'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install active_record-remote
|
20
|
+
|
21
|
+
## TODO
|
22
|
+
- [ ] implement for JSON
|
23
|
+
- [ ] implement for Flat File
|
24
|
+
- [ ] implement Rspec
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
1. Fork it ( https://github.com/[my-github-username]/active_record-remote/fork )
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
31
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'active_record/remote/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "active_record-remote"
|
8
|
+
spec.version = ActiveRecord::Remote::VERSION
|
9
|
+
spec.authors = ["Justin Grubbs"]
|
10
|
+
spec.email = ["justin@jgrubbs.net"]
|
11
|
+
spec.summary = %q{Active Record pattern for remote APIs}
|
12
|
+
spec.description = %q{Active Record pattern for remote APIs}
|
13
|
+
spec.homepage = "https://github.com/jGRUBBS/active_record-remote"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "virtus", "~> 1.0.5"
|
22
|
+
spec.add_dependency "activesupport", "~> 4.2.5"
|
23
|
+
spec.add_dependency "builder", "~> 3.2.2"
|
24
|
+
spec.add_dependency "activemodel", "~> 4.2.5"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
require 'active_model'
|
3
|
+
require 'active_support/core_ext/hash/conversions'
|
4
|
+
require 'active_support/core_ext/string/inflections'
|
5
|
+
require 'active_record/remote/core_ext/hash'
|
6
|
+
require 'active_record/remote/version'
|
7
|
+
require 'active_record/remote/base'
|
8
|
+
require 'active_record/remote/client'
|
9
|
+
require 'active_record/remote/response'
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'active_record/remote/helpers/association_helper'
|
2
|
+
require 'active_record/remote/helpers/request_helper'
|
3
|
+
require 'active_record/remote/helpers/serialization_helper'
|
4
|
+
require 'active_record/remote/helpers/xml_helper'
|
5
|
+
require 'active_record/remote/helpers/soap_helper'
|
6
|
+
|
7
|
+
module ActiveRecord
|
8
|
+
module Remote
|
9
|
+
class Base
|
10
|
+
|
11
|
+
class_attribute :action_path, :api_type, :operation_path, :base_element_name
|
12
|
+
|
13
|
+
include Virtus.model
|
14
|
+
include ActiveModel::Validations
|
15
|
+
extend ActiveRecord::Remote::Helpers::AssociationHelper
|
16
|
+
extend ActiveRecord::Remote::Helpers::RequestHelper
|
17
|
+
include ActiveRecord::Remote::Helpers::SerializationHelper
|
18
|
+
include ActiveRecord::Remote::Helpers::XMLHelper
|
19
|
+
include ActiveRecord::Remote::Helpers::SOAPHelper
|
20
|
+
|
21
|
+
attr_accessor :response, :raw_data, :parsed_data
|
22
|
+
|
23
|
+
def self.api_type(type)
|
24
|
+
self.api_type = type
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(options = {})
|
28
|
+
super(options.merge(custom_options))
|
29
|
+
end
|
30
|
+
|
31
|
+
def custom_options
|
32
|
+
# overwrite in subclass to provide custom options to initalizer
|
33
|
+
end
|
34
|
+
|
35
|
+
def save
|
36
|
+
@response = handle_response(request)
|
37
|
+
valid?
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.where(attrs)
|
41
|
+
instance = new(attrs)
|
42
|
+
instance.response = instance.handle_response(instance.request)
|
43
|
+
instance.parse_records
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.all
|
47
|
+
where({})
|
48
|
+
end
|
49
|
+
|
50
|
+
def request
|
51
|
+
request_body = send("as_#{api_type}")
|
52
|
+
client.api_type = api_type
|
53
|
+
client.request(request_body)
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_attributes(attrs)
|
57
|
+
attrs.each { |k, v| send("#{k}=", v) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def valid?
|
61
|
+
if response.present?
|
62
|
+
# all model validations may pass, but response
|
63
|
+
# may have contained an error message
|
64
|
+
response.success?
|
65
|
+
else
|
66
|
+
# use model validations
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def base_module
|
72
|
+
self.class.to_s.split('::').first.constantize
|
73
|
+
end
|
74
|
+
|
75
|
+
def full_module
|
76
|
+
self.class.to_s.split('::')[0..-2].join('::').constantize
|
77
|
+
end
|
78
|
+
|
79
|
+
def record_class
|
80
|
+
self.class.to_s.split('::').last
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse_records
|
84
|
+
data = response.data.is_a?(Array) ? response.data : [response.data]
|
85
|
+
return [] if data.compact.empty?
|
86
|
+
data.flat_map do |data_item|
|
87
|
+
instance = self.class.new
|
88
|
+
read_attributes = "#{record_class}ReadAttributes"
|
89
|
+
if full_module.const_defined?(read_attributes)
|
90
|
+
instance.extend(read_attributes.constantize)
|
91
|
+
end
|
92
|
+
attrs = data_item.transform_keys! {|k| k.downcase.to_sym }
|
93
|
+
instance.update_attributes(attrs)
|
94
|
+
instance
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def handle_response(response)
|
99
|
+
base_module.const_get("Response").new(
|
100
|
+
operation: self.class.operation_path,
|
101
|
+
raw_response: response,
|
102
|
+
instance: self
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def client
|
107
|
+
base_module.const_get("Client").new(self.class.action_path)
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "net/https"
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
module Remote
|
6
|
+
class Client
|
7
|
+
|
8
|
+
cattr_accessor :content_type, :host, :read_timeout, :api_type, :secure
|
9
|
+
attr_accessor :action
|
10
|
+
|
11
|
+
def initialize(action)
|
12
|
+
@action = action
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.content_type(content_type)
|
16
|
+
self.content_type = content_type
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.host(host)
|
20
|
+
self.host = host
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.read_timeout(read_timeout)
|
24
|
+
self.read_timeout = read_timeout
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.secure(secure)
|
28
|
+
self.secure = secure
|
29
|
+
end
|
30
|
+
|
31
|
+
def http
|
32
|
+
@http ||= Net::HTTP.new(host)
|
33
|
+
end
|
34
|
+
|
35
|
+
def formatted_action
|
36
|
+
action
|
37
|
+
end
|
38
|
+
|
39
|
+
def formatted_path
|
40
|
+
"/#{endpoint_path}/#{formatted_action}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def complete_request_url
|
44
|
+
"#{http_protocol}://#{host}#{formatted_path}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def http_protocol
|
48
|
+
secure ? "https" : "http"
|
49
|
+
end
|
50
|
+
|
51
|
+
def endpoint_path
|
52
|
+
# define in subclass
|
53
|
+
end
|
54
|
+
|
55
|
+
def request(request_body)
|
56
|
+
request = Net::HTTP::Post.new(formatted_path)
|
57
|
+
request.body = request_body
|
58
|
+
request.content_type = content_type
|
59
|
+
if secure
|
60
|
+
http.use_ssl = true
|
61
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
62
|
+
end
|
63
|
+
request.add_field("SOAPAction", "") if api_type == :soap
|
64
|
+
http.read_timeout = read_timeout if read_timeout
|
65
|
+
http.request(request)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def to_soap(options = {})
|
4
|
+
require 'active_support/builder' unless defined?(Builder)
|
5
|
+
|
6
|
+
options = options.dup
|
7
|
+
options[:indent] ||= 2
|
8
|
+
options[:root] ||= 'hash'
|
9
|
+
options[:soap_builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
|
10
|
+
|
11
|
+
soap_builder = options[:soap_builder]
|
12
|
+
|
13
|
+
soap_builder.Envelope xmlns: "http://schemas.xmlsoap.org/soap/envelope/" do
|
14
|
+
|
15
|
+
soap_builder.Body do
|
16
|
+
|
17
|
+
soap_builder.tag!(options[:operation], xmlns: options[:namespace]) do
|
18
|
+
soap_builder.tag!(options[:base_element], "\n#{build_internal_xml(options)}")
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_internal_xml(options = {})
|
27
|
+
options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
|
28
|
+
builder = options[:builder]
|
29
|
+
|
30
|
+
root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
|
31
|
+
|
32
|
+
builder.tag!(root) do
|
33
|
+
each { |key, value| ActiveSupport::XmlMini.to_tag(key, value, options) }
|
34
|
+
yield builder if block_given?
|
35
|
+
end
|
36
|
+
|
37
|
+
builder.target!.gsub(" ", "")
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ActiveRecord::Remote
|
2
|
+
module Helpers
|
3
|
+
module AssociationHelper
|
4
|
+
|
5
|
+
def has_many(association, options = {})
|
6
|
+
association_name = parse_association_name(association, options)
|
7
|
+
set_inflection(association, options)
|
8
|
+
self.attribute association, Array[association_klass(association_name)], options
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_association_name(association, options = {})
|
12
|
+
if options[:collection].present?
|
13
|
+
options[:collection]
|
14
|
+
else
|
15
|
+
association
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_inflection(association, options)
|
20
|
+
return if options[:collection].nil?
|
21
|
+
# since RLM has an irregular API we have to adjust the inflections
|
22
|
+
# so we can have children collections that do not match the parents
|
23
|
+
# i.e.
|
24
|
+
# <DETAILS>
|
25
|
+
# <LINE>
|
26
|
+
# instead of default behavior
|
27
|
+
# <DETAILS>
|
28
|
+
# <DETAIL>
|
29
|
+
#
|
30
|
+
# the code below dynamically adjusts active_support inflections
|
31
|
+
# here is a basic example
|
32
|
+
#
|
33
|
+
# ActiveSupport::Inflector.inflections do |inflect|
|
34
|
+
# inflect.singular 'DETAILS', 'LINE'
|
35
|
+
# end
|
36
|
+
if options[:strict]
|
37
|
+
assoc_name = association.to_s
|
38
|
+
collection = options[:collection].to_s
|
39
|
+
else
|
40
|
+
assoc_name = association.to_s.upcase
|
41
|
+
collection = options[:collection].to_s.upcase
|
42
|
+
end
|
43
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
44
|
+
inflect.singular assoc_name, collection
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def association_klass(name)
|
49
|
+
singular = name.to_s.singularize
|
50
|
+
parent_module = to_s.split('::')[0..-2].join('::').constantize
|
51
|
+
parent_module.const_get(singular.classify)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveRecord::Remote
|
2
|
+
module Helpers
|
3
|
+
module RequestHelper
|
4
|
+
|
5
|
+
def action(kind)
|
6
|
+
self.action_path = kind
|
7
|
+
end
|
8
|
+
|
9
|
+
def operation(kind)
|
10
|
+
self.operation_path = kind
|
11
|
+
end
|
12
|
+
|
13
|
+
def base_element(name)
|
14
|
+
self.base_element_name = name
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ActiveRecord::Remote
|
2
|
+
module Helpers
|
3
|
+
module SerializationHelper
|
4
|
+
|
5
|
+
def serializable_hash
|
6
|
+
Hash.new.tap do |attribute_hash|
|
7
|
+
attribute_set.each do |attribute|
|
8
|
+
serialize_attribute(attribute_hash, attribute)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def serialize_attribute(attribute_hash, attribute)
|
14
|
+
return if attributes[attribute.name].nil?
|
15
|
+
name = _attribute_name(attribute)
|
16
|
+
attribute_hash[name] = _serialize(attributes[attribute.name], attribute)
|
17
|
+
end
|
18
|
+
|
19
|
+
def _attribute_name(attribute)
|
20
|
+
if !!attribute.options[:as]
|
21
|
+
attribute.options[:as]
|
22
|
+
elsif !!attribute.options[:strict]
|
23
|
+
attribute.name
|
24
|
+
else
|
25
|
+
attribute.name.upcase
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def _serialize(serialized, attribute = nil)
|
30
|
+
if serialized.respond_to?(:serializable_hash)
|
31
|
+
serialized.serializable_hash
|
32
|
+
else
|
33
|
+
case serialized
|
34
|
+
when Array
|
35
|
+
serialized.map { |attr| _serialize(attr) }
|
36
|
+
when BigDecimal
|
37
|
+
serialized.to_s("F")
|
38
|
+
when Hash
|
39
|
+
Hash[
|
40
|
+
serialized.map do |k, v|
|
41
|
+
k = attribute.options[:strict] ? k : k.upcase
|
42
|
+
[k, v]
|
43
|
+
end
|
44
|
+
]
|
45
|
+
else
|
46
|
+
serialized
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveRecord::Remote
|
2
|
+
module Helpers
|
3
|
+
module SOAPHelper
|
4
|
+
|
5
|
+
def as_soap
|
6
|
+
serializable_hash.to_soap(soap_options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def soap_options
|
10
|
+
{
|
11
|
+
dasherize: false,
|
12
|
+
skip_types: true,
|
13
|
+
omit_nils: true
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveRecord::Remote
|
2
|
+
module Helpers
|
3
|
+
module XMLHelper
|
4
|
+
|
5
|
+
def as_xml
|
6
|
+
serializable_hash.to_xml(xml_options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def xml_options
|
10
|
+
{
|
11
|
+
root: "ITEM_FILTER",
|
12
|
+
dasherize: false,
|
13
|
+
skip_types: true
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Remote
|
3
|
+
class Response
|
4
|
+
|
5
|
+
attr_accessor :parsed_response, :options
|
6
|
+
|
7
|
+
alias_method :parsed, :parsed_response
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
handle_response(options[:raw_response])
|
12
|
+
end
|
13
|
+
|
14
|
+
def operation
|
15
|
+
options[:operation]
|
16
|
+
end
|
17
|
+
|
18
|
+
def record_instance
|
19
|
+
options[:instance]
|
20
|
+
end
|
21
|
+
|
22
|
+
def success?
|
23
|
+
record_instance.errors.blank?
|
24
|
+
end
|
25
|
+
|
26
|
+
def handle_response(response)
|
27
|
+
# implement in subclass
|
28
|
+
end
|
29
|
+
|
30
|
+
def response_message
|
31
|
+
# implement in subclass
|
32
|
+
end
|
33
|
+
|
34
|
+
def valid?
|
35
|
+
# implement in subclass
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_record-remote
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Grubbs
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: virtus
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.5
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.2.5
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.2.5
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: builder
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.2.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.2.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activemodel
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.2.5
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.2.5
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
description: Active Record pattern for remote APIs
|
98
|
+
email:
|
99
|
+
- justin@jgrubbs.net
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- Gemfile
|
106
|
+
- LICENSE.txt
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- active_record-remote.gemspec
|
110
|
+
- lib/active_record/remote.rb
|
111
|
+
- lib/active_record/remote/base.rb
|
112
|
+
- lib/active_record/remote/client.rb
|
113
|
+
- lib/active_record/remote/core_ext/hash.rb
|
114
|
+
- lib/active_record/remote/helpers/association_helper.rb
|
115
|
+
- lib/active_record/remote/helpers/request_helper.rb
|
116
|
+
- lib/active_record/remote/helpers/serialization_helper.rb
|
117
|
+
- lib/active_record/remote/helpers/soap_helper.rb
|
118
|
+
- lib/active_record/remote/helpers/xml_helper.rb
|
119
|
+
- lib/active_record/remote/response.rb
|
120
|
+
- lib/active_record/remote/version.rb
|
121
|
+
homepage: https://github.com/jGRUBBS/active_record-remote
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
metadata: {}
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 2.2.2
|
142
|
+
signing_key:
|
143
|
+
specification_version: 4
|
144
|
+
summary: Active Record pattern for remote APIs
|
145
|
+
test_files: []
|