contentful 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.README.md.swp +0 -0
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/.travis.yml +10 -0
- data/ChangeLog.md +3 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +193 -0
- data/Rakefile +30 -0
- data/contentful.gemspec +31 -0
- data/do_request.sh +5 -0
- data/doc/Contentful.html +131 -0
- data/doc/Contentful/AccessDenied.html +158 -0
- data/doc/Contentful/Array.html +346 -0
- data/doc/Contentful/Asset.html +315 -0
- data/doc/Contentful/BadRequest.html +158 -0
- data/doc/Contentful/Client.html +1407 -0
- data/doc/Contentful/ContentType.html +183 -0
- data/doc/Contentful/DynamicEntry.html +333 -0
- data/doc/Contentful/Entry.html +198 -0
- data/doc/Contentful/Error.html +413 -0
- data/doc/Contentful/Field.html +161 -0
- data/doc/Contentful/File.html +160 -0
- data/doc/Contentful/Link.html +275 -0
- data/doc/Contentful/Locale.html +161 -0
- data/doc/Contentful/NotFound.html +158 -0
- data/doc/Contentful/Request.html +669 -0
- data/doc/Contentful/Resource.html +606 -0
- data/doc/Contentful/Resource/AssetFields.html +413 -0
- data/doc/Contentful/Resource/AssetFields/ClassMethods.html +174 -0
- data/doc/Contentful/Resource/ClassMethods.html +271 -0
- data/doc/Contentful/Resource/Fields.html +398 -0
- data/doc/Contentful/Resource/Fields/ClassMethods.html +187 -0
- data/doc/Contentful/Resource/SystemProperties.html +444 -0
- data/doc/Contentful/Resource/SystemProperties/ClassMethods.html +174 -0
- data/doc/Contentful/ResourceBuilder.html +1400 -0
- data/doc/Contentful/Response.html +546 -0
- data/doc/Contentful/ServerError.html +158 -0
- data/doc/Contentful/Space.html +183 -0
- data/doc/Contentful/Support.html +198 -0
- data/doc/Contentful/Unauthorized.html +158 -0
- data/doc/Contentful/UnparsableJson.html +158 -0
- data/doc/Contentful/UnparsableResource.html +158 -0
- data/doc/_index.html +410 -0
- data/doc/class_list.html +54 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +338 -0
- data/doc/file.README.html +214 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +26 -0
- data/doc/index.html +214 -0
- data/doc/js/app.js +219 -0
- data/doc/js/full_list.js +178 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +533 -0
- data/doc/top-level-namespace.html +112 -0
- data/examples/custom_classes.rb +43 -0
- data/examples/dynamic_entries.rb +126 -0
- data/examples/example_queries.rb +27 -0
- data/examples/raise_errors.rb +22 -0
- data/examples/raw_mode.rb +15 -0
- data/examples/resource_mapping.rb +33 -0
- data/lib/contentful.rb +3 -0
- data/lib/contentful/array.rb +47 -0
- data/lib/contentful/asset.rb +34 -0
- data/lib/contentful/client.rb +193 -0
- data/lib/contentful/content_type.rb +16 -0
- data/lib/contentful/dynamic_entry.rb +54 -0
- data/lib/contentful/entry.rb +12 -0
- data/lib/contentful/error.rb +52 -0
- data/lib/contentful/field.rb +16 -0
- data/lib/contentful/file.rb +13 -0
- data/lib/contentful/link.rb +20 -0
- data/lib/contentful/locale.rb +12 -0
- data/lib/contentful/location.rb +12 -0
- data/lib/contentful/request.rb +37 -0
- data/lib/contentful/resource.rb +146 -0
- data/lib/contentful/resource/asset_fields.rb +50 -0
- data/lib/contentful/resource/fields.rb +39 -0
- data/lib/contentful/resource/system_properties.rb +48 -0
- data/lib/contentful/resource_builder.rb +197 -0
- data/lib/contentful/response.rb +64 -0
- data/lib/contentful/space.rb +14 -0
- data/lib/contentful/support.rb +18 -0
- data/lib/contentful/version.rb +3 -0
- data/spec/array_spec.rb +69 -0
- data/spec/asset_spec.rb +62 -0
- data/spec/auto_includes_spec.rb +12 -0
- data/spec/client_class_spec.rb +59 -0
- data/spec/client_configuration_spec.rb +197 -0
- data/spec/coercions_spec.rb +10 -0
- data/spec/content_type_spec.rb +44 -0
- data/spec/dynamic_entry_spec.rb +34 -0
- data/spec/entry_spec.rb +53 -0
- data/spec/error_class_spec.rb +60 -0
- data/spec/error_requests_spec.rb +32 -0
- data/spec/field_spec.rb +36 -0
- data/spec/file_spec.rb +28 -0
- data/spec/fixtures/json_responses/content_type.json +83 -0
- data/spec/fixtures/json_responses/not_found.json +13 -0
- data/spec/fixtures/json_responses/nyancat.json +48 -0
- data/spec/fixtures/json_responses/unparsable.json +13 -0
- data/spec/fixtures/vcr_cassettes/array.yml +288 -0
- data/spec/fixtures/vcr_cassettes/array_page_1.yml +106 -0
- data/spec/fixtures/vcr_cassettes/array_page_2.yml +73 -0
- data/spec/fixtures/vcr_cassettes/asset.yml +96 -0
- data/spec/fixtures/vcr_cassettes/bad_request.yml +76 -0
- data/spec/fixtures/vcr_cassettes/content_type.yml +147 -0
- data/spec/fixtures/vcr_cassettes/entries.yml +561 -0
- data/spec/fixtures/vcr_cassettes/entry.yml +112 -0
- data/spec/fixtures/vcr_cassettes/entry_cache.yml +288 -0
- data/spec/fixtures/vcr_cassettes/field.yml +147 -0
- data/spec/fixtures/vcr_cassettes/locale.yml +81 -0
- data/spec/fixtures/vcr_cassettes/location.yml +305 -0
- data/spec/fixtures/vcr_cassettes/not_found.yml +71 -0
- data/spec/fixtures/vcr_cassettes/nyancat.yml +112 -0
- data/spec/fixtures/vcr_cassettes/nyancat_include.yml +112 -0
- data/spec/fixtures/vcr_cassettes/reloaded_entry.yml +112 -0
- data/spec/fixtures/vcr_cassettes/space.yml +81 -0
- data/spec/fixtures/vcr_cassettes/unauthorized.yml +64 -0
- data/spec/link_spec.rb +40 -0
- data/spec/locale_spec.rb +20 -0
- data/spec/location_spec.rb +30 -0
- data/spec/request_spec.rb +48 -0
- data/spec/resource_spec.rb +52 -0
- data/spec/response_spec.rb +50 -0
- data/spec/space_spec.rb +36 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/support/client.rb +6 -0
- data/spec/support/json_responses.rb +11 -0
- data/spec/support/vcr.rb +16 -0
- metadata +374 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
require_relative 'resource/system_properties'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Contentful
|
5
|
+
# Include this module to declare a class to be a contentful resource.
|
6
|
+
# This is done by the default in the existing resource classes
|
7
|
+
#
|
8
|
+
# You can define your own classes that behave like contentful resources:
|
9
|
+
# See examples/custom_classes.rb to see how.
|
10
|
+
#
|
11
|
+
# Take a look at examples/resource_mapping.rb on how to register them to be returned
|
12
|
+
# by the client by default
|
13
|
+
module Resource
|
14
|
+
COERCIONS = {
|
15
|
+
string: ->(v){ v.to_s },
|
16
|
+
integer: ->(v){ v.to_i },
|
17
|
+
float: ->(v){ v.to_f },
|
18
|
+
boolean: ->(v){ !!v },
|
19
|
+
date: ->(v){ DateTime.parse(v) },
|
20
|
+
}
|
21
|
+
|
22
|
+
attr_reader :properties, :request, :client
|
23
|
+
|
24
|
+
def initialize(object, request = nil, client = nil)
|
25
|
+
self.class.update_coercions!
|
26
|
+
|
27
|
+
@properties = extract_from_object object, :property, self.class.property_coercions.keys
|
28
|
+
@request = request
|
29
|
+
@client = client
|
30
|
+
end
|
31
|
+
|
32
|
+
def inspect(info = nil)
|
33
|
+
properties_info = properties.empty? ? "" : " @properties=#{properties.inspect}"
|
34
|
+
"#<#{self.class}:#{properties_info}#{info}>"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns true for resources that behave like an array
|
38
|
+
def array?
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
# Resources that don't include SystemProperties return nil for #sys
|
43
|
+
def sys
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
# Resources that don't include Fields or AssetFields return nil for #fields
|
48
|
+
def fields
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
# Issues the request that was made to fetch this response again.
|
53
|
+
# Only works for top-level resources
|
54
|
+
def reload
|
55
|
+
if request
|
56
|
+
request.get
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def extract_from_object(object, namespace, keys = nil)
|
66
|
+
if object
|
67
|
+
keys ||= object.keys
|
68
|
+
keys.each.with_object({}){ |name, res|
|
69
|
+
res[name.to_sym] = coerce_value_or_array(
|
70
|
+
object.is_a?(::Array) ? object : object[name.to_s],
|
71
|
+
self.class.public_send(:"#{namespace}_coercions")[name.to_sym],
|
72
|
+
)
|
73
|
+
}
|
74
|
+
else
|
75
|
+
{}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def coerce_value_or_array(value, what = nil)
|
80
|
+
if value.is_a? ::Array
|
81
|
+
value.map{ |v| coerce_or_create_class(v, what) }
|
82
|
+
else
|
83
|
+
coerce_or_create_class(value, what)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def coerce_or_create_class(value, what)
|
88
|
+
case what
|
89
|
+
when Symbol
|
90
|
+
COERCIONS[what] ? COERCIONS[what][value] : value
|
91
|
+
when Class
|
92
|
+
what.new(value, client)
|
93
|
+
else
|
94
|
+
value
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Register the resources properties on class level by using the #property method
|
99
|
+
module ClassMethods
|
100
|
+
def property_coercions
|
101
|
+
@property_coercions ||= {}
|
102
|
+
end
|
103
|
+
|
104
|
+
# Defines which properties of a resource your class expects
|
105
|
+
# Define them in :camelCase, they will be available as #snake_cased methods
|
106
|
+
#
|
107
|
+
# You can pass in a second "type" argument:
|
108
|
+
# - If it is a class, it will be initialized for the property
|
109
|
+
# - Symbols are looked up in the COERCION constant for a lambda that
|
110
|
+
# defines a type conversion to apply
|
111
|
+
#
|
112
|
+
# Note: This second argument is not meant for contentful sub-resources,
|
113
|
+
# but for structured objects (like locales in a space)
|
114
|
+
# Sub-resources are handled by the resource builder
|
115
|
+
def property(name, property_class = nil)
|
116
|
+
property_coercions[name.to_sym] = property_class
|
117
|
+
define_method Contentful::Support.snakify(name) do
|
118
|
+
properties[name.to_sym]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Ensure inherited classes pick up coercions
|
123
|
+
def update_coercions!
|
124
|
+
return if @coercions_updated
|
125
|
+
|
126
|
+
if superclass.respond_to? :property_coercions
|
127
|
+
@property_coercions = superclass.property_coercions.dup.merge(@property_coercions || {})
|
128
|
+
end
|
129
|
+
|
130
|
+
if superclass.respond_to? :sys_coercions
|
131
|
+
@sys_coercions = superclass.sys_coercions.dup.merge(@sys_coercions || {})
|
132
|
+
end
|
133
|
+
|
134
|
+
if superclass.respond_to? :fields_coercions
|
135
|
+
@fields_coercions = superclass.fields_coercions.dup.merge(@fields_coercions || {})
|
136
|
+
end
|
137
|
+
|
138
|
+
@coercions_updated = true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.included(base)
|
143
|
+
base.extend(ClassMethods)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative '../file'
|
2
|
+
|
3
|
+
module Contentful
|
4
|
+
module Resource
|
5
|
+
# Special fields for Asset. Don't include together wit Contentful::Resource::Fields
|
6
|
+
#
|
7
|
+
# It depends on system properties being available
|
8
|
+
module AssetFields
|
9
|
+
FIELDS_COERCIONS = {
|
10
|
+
title: :string,
|
11
|
+
description: :string,
|
12
|
+
file: File,
|
13
|
+
}
|
14
|
+
|
15
|
+
def fields
|
16
|
+
@fields[locale]
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(object, *)
|
20
|
+
super
|
21
|
+
@fields = {}
|
22
|
+
@fields[locale] = extract_from_object object["fields"], :fields
|
23
|
+
end
|
24
|
+
|
25
|
+
def inspect(info = nil)
|
26
|
+
if fields.empty?
|
27
|
+
super(info)
|
28
|
+
else
|
29
|
+
super("#{info} @fields=#{fields.inspect}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module ClassMethods
|
34
|
+
def fields_coercions
|
35
|
+
FIELDS_COERCIONS
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.included(base)
|
40
|
+
base.extend(ClassMethods)
|
41
|
+
|
42
|
+
base.fields_coercions.keys.each{ |name|
|
43
|
+
base.send :define_method, Contentful::Support.snakify(name) do
|
44
|
+
fields[name.to_sym]
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Contentful
|
2
|
+
module Resource
|
3
|
+
# Include this module into your Resource class to enable it
|
4
|
+
# to deal with entry fields (but not asset fields)
|
5
|
+
#
|
6
|
+
# It depends on system properties being available
|
7
|
+
module Fields
|
8
|
+
# Returns all fields of the asset
|
9
|
+
def fields
|
10
|
+
@fields[locale]
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(object, *)
|
14
|
+
super
|
15
|
+
@fields = {}
|
16
|
+
@fields[locale] = extract_from_object object["fields"], :fields
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect(info = nil)
|
20
|
+
if fields.empty?
|
21
|
+
super(info)
|
22
|
+
else
|
23
|
+
super("#{info} @fields=#{fields.inspect}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
# No coercions, since no content type available
|
29
|
+
def fields_coercions
|
30
|
+
{}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.included(base)
|
35
|
+
base.extend(ClassMethods)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Contentful
|
2
|
+
module Resource
|
3
|
+
# Adds the feature to have system properties to a Resource.
|
4
|
+
module SystemProperties
|
5
|
+
SYS_COERCIONS = {
|
6
|
+
type: :string,
|
7
|
+
id: :string,
|
8
|
+
space: nil,
|
9
|
+
contentType: nil,
|
10
|
+
linkType: :string,
|
11
|
+
revision: :integer,
|
12
|
+
createdAt: :date,
|
13
|
+
updatedAt: :date,
|
14
|
+
locale: :string,
|
15
|
+
}
|
16
|
+
attr_reader :sys
|
17
|
+
|
18
|
+
def initialize(object, *)
|
19
|
+
super
|
20
|
+
@sys = extract_from_object object["sys"], :sys
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect(info = nil)
|
24
|
+
if sys.empty?
|
25
|
+
super(info)
|
26
|
+
else
|
27
|
+
super("#{info} @sys=#{sys.inspect}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
def sys_coercions
|
33
|
+
SYS_COERCIONS
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.included(base)
|
38
|
+
base.extend(ClassMethods)
|
39
|
+
|
40
|
+
base.sys_coercions.keys.each{ |name|
|
41
|
+
base.send :define_method, Contentful::Support.snakify(name) do
|
42
|
+
sys[name.to_sym]
|
43
|
+
end
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require_relative 'error'
|
2
|
+
require_relative 'resource'
|
3
|
+
require_relative 'space'
|
4
|
+
require_relative 'content_type'
|
5
|
+
require_relative 'entry'
|
6
|
+
require_relative 'dynamic_entry'
|
7
|
+
require_relative 'asset'
|
8
|
+
require_relative 'array'
|
9
|
+
require_relative 'link'
|
10
|
+
|
11
|
+
module Contentful
|
12
|
+
# Transforms a Contentful::Response into a Contentful::Resource or a Contentful::Error
|
13
|
+
# See example/resource_mapping.rb for avanced usage
|
14
|
+
class ResourceBuilder
|
15
|
+
DEFAULT_RESOURCE_MAPPING = {
|
16
|
+
'Space' => Space,
|
17
|
+
'ContentType' => ContentType,
|
18
|
+
'Entry' => :try_dynamic_entry,
|
19
|
+
'Asset' => Asset,
|
20
|
+
'Array' => Array,
|
21
|
+
'Link' => Link,
|
22
|
+
}
|
23
|
+
|
24
|
+
attr_reader :client, :response, :resource_mapping
|
25
|
+
|
26
|
+
|
27
|
+
def initialize(client, response, resource_mapping = {})
|
28
|
+
@response = response
|
29
|
+
@client = client
|
30
|
+
@included_resources = {}
|
31
|
+
@resource_mapping = default_resource_mapping.merge(resource_mapping)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Starts the parsing process.
|
35
|
+
# Either returns an Error, or the parsed Resource
|
36
|
+
def run
|
37
|
+
case response.status
|
38
|
+
when :contentful_error
|
39
|
+
Error[response.raw.response.status].new(response)
|
40
|
+
when :unparsable_json
|
41
|
+
UnparsableJson.new(response)
|
42
|
+
when :not_contentful
|
43
|
+
Error.new(response)
|
44
|
+
else
|
45
|
+
begin
|
46
|
+
create_all_resources!
|
47
|
+
rescue UnparsableResource => error
|
48
|
+
error
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# PARSING MECHANISM
|
54
|
+
# - raise error if response not valid
|
55
|
+
# - look for included objects and parse them to resources
|
56
|
+
# - parse main object to resource
|
57
|
+
# - replace links in included resources with included resources
|
58
|
+
# - replace links in main resource with included resources
|
59
|
+
# - return main resource
|
60
|
+
def create_all_resources!
|
61
|
+
create_included_resources! response.object["includes"]
|
62
|
+
res = create_resource(response.object)
|
63
|
+
|
64
|
+
unless @included_resources.empty?
|
65
|
+
replace_links_in_included_resources_with_included_resources
|
66
|
+
replace_links_with_included_resources(res)
|
67
|
+
end
|
68
|
+
|
69
|
+
res
|
70
|
+
end
|
71
|
+
|
72
|
+
# Creates a single resource from the
|
73
|
+
def create_resource(object)
|
74
|
+
res = detect_resource_class(object).new(object, response.request, client)
|
75
|
+
replace_children res, object
|
76
|
+
replace_children_array(res, :items) if res.array?
|
77
|
+
|
78
|
+
res
|
79
|
+
end
|
80
|
+
|
81
|
+
# When using Dynamic Entry Mode: Automatically converts Entry to DynamicEntry
|
82
|
+
def try_dynamic_entry(object)
|
83
|
+
get_dynamic_entry(object) || Entry
|
84
|
+
end
|
85
|
+
|
86
|
+
# Finds the proper DynamicEntry class for an entry
|
87
|
+
def get_dynamic_entry(object)
|
88
|
+
if id = object["sys"] &&
|
89
|
+
object["sys"]["contentType"] &&
|
90
|
+
object["sys"]["contentType"]["sys"] &&
|
91
|
+
object["sys"]["contentType"]["sys"]["id"]
|
92
|
+
client.dynamic_entry_cache[id.to_sym]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Uses the resource mapping to find the proper Resource class to initialize
|
97
|
+
# for this Response object type
|
98
|
+
#
|
99
|
+
# The mapping value can be a
|
100
|
+
# - Class
|
101
|
+
# - Proc: Will be called, expected to return the proper Class
|
102
|
+
# - Symbol: Will be called as method of the ResourceBuilder itself
|
103
|
+
def detect_resource_class(object)
|
104
|
+
type = object["sys"] && object["sys"]["type"]
|
105
|
+
case res_class = resource_mapping[type]
|
106
|
+
when Symbol
|
107
|
+
public_send(res_class, object)
|
108
|
+
when Proc
|
109
|
+
res_class[object]
|
110
|
+
when nil
|
111
|
+
raise UnsparsableResource.new(response)
|
112
|
+
else
|
113
|
+
res_class
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# The default mapping for #detect_resource_class
|
118
|
+
def default_resource_mapping
|
119
|
+
DEFAULT_RESOURCE_MAPPING
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def detect_child_objects(object)
|
126
|
+
if object.is_a?(Hash)
|
127
|
+
object.select{ |k,v| v.is_a?(Hash) && v.has_key?("sys") }
|
128
|
+
else
|
129
|
+
{}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def replace_children(res, object)
|
134
|
+
object.each{ |name, potential_objects|
|
135
|
+
detect_child_objects(potential_objects).each{ |child_name, child_object|
|
136
|
+
res.public_send(name)[child_name.to_sym] = create_resource(child_object)
|
137
|
+
}
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
def replace_children_array(res, array_field)
|
142
|
+
items = res.public_send(array_field)
|
143
|
+
items.map!{ |resource_object| create_resource(resource_object) }
|
144
|
+
end
|
145
|
+
|
146
|
+
def create_included_resources!(included_objects)
|
147
|
+
if included_objects
|
148
|
+
included_objects.each{ |type, objects|
|
149
|
+
@included_resources[type] = Hash[
|
150
|
+
objects.map{ |object|
|
151
|
+
res = create_resource(object)
|
152
|
+
[res.id, res]
|
153
|
+
}
|
154
|
+
]
|
155
|
+
}
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def replace_links_with_included_resources(res)
|
160
|
+
[:properties, :sys, :fields].each{ |_what|
|
161
|
+
if what = res.public_send(_what)
|
162
|
+
what.each{ |name, child_res|
|
163
|
+
replace_link_or_check_recursively child_res, what, name, res
|
164
|
+
}
|
165
|
+
end
|
166
|
+
}
|
167
|
+
if res.array?
|
168
|
+
res.each.with_index{ |child_res, index|
|
169
|
+
replace_link_or_check_recursively child_res, res.items, index, child_res
|
170
|
+
}
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def replace_link_or_check_recursively(res, what, name, resource_to_replace)
|
175
|
+
if res.is_a? Link
|
176
|
+
maybe_replace_link(res, what, name)
|
177
|
+
elsif res.is_a?(Resource) && res.sys
|
178
|
+
replace_links_with_included_resources(resource_to_replace)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def replace_links_in_included_resources_with_included_resources
|
183
|
+
@included_resources.each{ |_, for_type|
|
184
|
+
for_type.each{ |_, res|
|
185
|
+
replace_links_with_included_resources(res)
|
186
|
+
}
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
def maybe_replace_link(resource, parent, index)
|
191
|
+
if @included_resources[resource.link_type] &&
|
192
|
+
@included_resources[resource.link_type].has_key?(resource.id)
|
193
|
+
parent[index] = @included_resources[resource.link_type][resource.id]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|