syncano 4.0.0.alpha4 → 4.0.0.pre
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 -1
- data/README.md +1 -13
- data/circle.yml +1 -1
- data/lib/active_attr/dirty.rb +26 -0
- data/lib/active_attr/typecasting/hash_typecaster.rb +34 -0
- data/lib/active_attr/typecasting_override.rb +29 -0
- data/lib/syncano.rb +9 -55
- data/lib/syncano/api.rb +2 -20
- data/lib/syncano/connection.rb +47 -48
- data/lib/syncano/model/associations.rb +121 -0
- data/lib/syncano/model/associations/base.rb +38 -0
- data/lib/syncano/model/associations/belongs_to.rb +30 -0
- data/lib/syncano/model/associations/has_many.rb +75 -0
- data/lib/syncano/model/associations/has_one.rb +22 -0
- data/lib/syncano/model/base.rb +257 -0
- data/lib/syncano/model/callbacks.rb +49 -0
- data/lib/syncano/model/scope_builder.rb +158 -0
- data/lib/syncano/query_builder.rb +7 -11
- data/lib/syncano/resources/base.rb +66 -91
- data/lib/syncano/schema.rb +159 -10
- data/lib/syncano/schema/attribute_definition.rb +0 -75
- data/lib/syncano/schema/resource_definition.rb +2 -24
- data/lib/syncano/version.rb +1 -1
- data/spec/integration/syncano_spec.rb +26 -268
- data/spec/spec_helper.rb +1 -3
- data/spec/unit/connection_spec.rb +74 -34
- data/spec/unit/query_builder_spec.rb +2 -2
- data/spec/unit/resources_base_spec.rb +64 -125
- data/spec/unit/schema/resource_definition_spec.rb +3 -24
- data/spec/unit/schema_spec.rb +55 -5
- data/spec/unit/syncano_spec.rb +9 -45
- data/syncano.gemspec +0 -5
- metadata +14 -87
- data/lib/syncano/api/endpoints.rb +0 -17
- data/lib/syncano/poller.rb +0 -55
- data/lib/syncano/resources.rb +0 -158
- data/lib/syncano/resources/paths.rb +0 -48
- data/lib/syncano/resources/resource_invalid.rb +0 -15
- data/lib/syncano/response.rb +0 -55
- data/lib/syncano/schema/endpoints_whitelist.rb +0 -40
- data/lib/syncano/upload_io.rb +0 -7
- data/spec/unit/resources/paths_spec.rb +0 -21
- data/spec/unit/response_spec.rb +0 -75
- data/spec/unit/schema/attribute_definition_spec.rb +0 -18
data/spec/unit/schema_spec.rb
CHANGED
@@ -1,16 +1,66 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
2
|
|
3
|
+
|
4
|
+
require 'rspec/expectations'
|
5
|
+
require 'active_attr/matchers/have_attribute_matcher'
|
6
|
+
require 'shoulda-matchers'
|
7
|
+
|
3
8
|
describe Syncano::Schema do
|
4
|
-
|
9
|
+
include ActiveAttr::Matchers
|
10
|
+
|
11
|
+
let(:connection) { double("connection") }
|
12
|
+
|
13
|
+
subject { described_class.new connection }
|
5
14
|
|
6
15
|
before do
|
7
|
-
expect(connection).to receive(:request).with(:get, described_class
|
16
|
+
expect(connection).to receive(:request).with(:get, described_class::SCHEMA_PATH) { schema }
|
17
|
+
|
18
|
+
Syncano::Resources.instance_eval do
|
19
|
+
constants.each do |const|
|
20
|
+
if ![:Base, :Collection, :Space].include?(const) && const_defined?(const)
|
21
|
+
remove_const const
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
8
25
|
end
|
9
26
|
|
10
|
-
|
27
|
+
describe 'process!' do
|
28
|
+
it 'defintes classes according to the schema' do
|
29
|
+
expect { Syncano::Resources::Class }.to raise_error(NameError)
|
30
|
+
|
31
|
+
subject.process!
|
32
|
+
|
33
|
+
expect { Syncano::Resources::Class }.to_not raise_error
|
34
|
+
|
35
|
+
expect(Syncano::Resources::Class).to have_attribute(:name)
|
36
|
+
expect(Syncano::Resources::Class).to have_attribute(:status)
|
37
|
+
expect(Syncano::Resources::Class).to have_attribute(:created_at)
|
38
|
+
expect(Syncano::Resources::Class).to have_attribute(:description)
|
39
|
+
expect(Syncano::Resources::Class).to have_attribute(:updated_at)
|
40
|
+
expect(Syncano::Resources::Class).to have_attribute(:objects_count)
|
41
|
+
expect(Syncano::Resources::Class).to have_attribute(:metadata)
|
42
|
+
expect(Syncano::Resources::Class).to have_attribute(:revision)
|
43
|
+
|
44
|
+
class_instance = Syncano::Resources::Class.new(connection, {}, { links: {} })
|
45
|
+
|
46
|
+
expect(class_instance).to validate_presence_of(:name)
|
47
|
+
expect(class_instance).to validate_length_of(:name).is_at_most(50)
|
48
|
+
|
49
|
+
expect(class_instance).to respond_to(:objects)
|
50
|
+
|
51
|
+
code_box_instance = Syncano::Resources::CodeBox.new(connection, {}, { links: {} })
|
52
|
+
expect(code_box_instance).to validate_inclusion_of(:runtime_name).
|
53
|
+
in_array(%w(nodejs ruby python))
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'defines foreign keys attributes when attributes names collide with links' do
|
58
|
+
subject.process!
|
59
|
+
|
60
|
+
schedule_instance = Syncano::Resources::Schedule.new connection, {}, links: {}
|
11
61
|
|
12
|
-
|
13
|
-
|
62
|
+
expect(schedule_instance).to respond_to(:codebox)
|
63
|
+
end
|
14
64
|
end
|
15
65
|
|
16
66
|
def schema
|
data/spec/unit/syncano_spec.rb
CHANGED
@@ -5,59 +5,23 @@ describe Syncano do
|
|
5
5
|
describe '#connect' do
|
6
6
|
let(:email) { 'kiszka@koza.com' }
|
7
7
|
let(:password) { 'kiszonka' }
|
8
|
-
let(:
|
8
|
+
let(:options) { { email: email, password: password } }
|
9
9
|
let(:api_key) { 'kozakoza123' }
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
specify do
|
19
|
-
expect(Syncano.connect(email_options)).to be_kind_of(Syncano::API)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'api key' do
|
24
|
-
before do
|
25
|
-
stub_schema_request
|
26
|
-
end
|
27
|
-
|
28
|
-
specify do
|
29
|
-
expect(Syncano.connect(api_key: api_key)).to be_kind_of(Syncano::API)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'with credentials in ENV variables' do
|
35
|
-
before do
|
36
|
-
@old_api_key = ENV['SYNCANO_API_KEY']
|
37
|
-
ENV['SYNCANO_API_KEY'] = api_key
|
38
|
-
|
39
|
-
stub_schema_request
|
40
|
-
end
|
41
|
-
|
42
|
-
after do
|
43
|
-
ENV['SYNCANO_API_KEY'] = @old_api_key
|
44
|
-
end
|
45
|
-
|
46
|
-
specify { expect(Syncano.connect).to be_kind_of(Syncano::API) }
|
47
|
-
end
|
11
|
+
before do
|
12
|
+
stub_request(:post, endpoint_uri('account/auth/'))
|
13
|
+
.with(body: options)
|
14
|
+
.to_return(status: 200,
|
15
|
+
body: generate_body(id: 15, email: email, first_name: '', last_name: '', account_key: api_key))
|
48
16
|
|
49
|
-
def stub_schema_request
|
50
17
|
stub_request(:get, endpoint_uri('schema/'))
|
51
18
|
.with(headers: { 'X-Api-Key' => api_key })
|
52
19
|
.to_return(status: 200, body: generate_body([]))
|
53
|
-
end
|
54
20
|
|
55
|
-
|
56
|
-
|
57
|
-
.with(body: email_options)
|
58
|
-
.to_return(status: 200,
|
59
|
-
body: generate_body(id: 15, email: email, first_name: '', last_name: '', account_key: api_key))
|
21
|
+
expect_any_instance_of(Syncano::Connection)
|
22
|
+
.to receive(:authenticated?)
|
60
23
|
end
|
61
24
|
|
25
|
+
specify { expect(Syncano.connect(options)).to be_kind_of(Syncano::API) }
|
62
26
|
end
|
63
27
|
end
|
data/syncano.gemspec
CHANGED
@@ -24,9 +24,4 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_dependency 'faraday', '~> 0.9'
|
25
25
|
spec.add_dependency 'activesupport', '>= 4.0'
|
26
26
|
spec.add_dependency 'active_attr', '~> 0.8'
|
27
|
-
spec.add_dependency 'dirty_hashy', '~> 0.2'
|
28
|
-
spec.add_dependency 'celluloid'
|
29
|
-
spec.add_dependency 'celluloid-io'
|
30
|
-
spec.add_dependency 'mimetype-fu'
|
31
|
-
spec.add_dependency 'http', '= 0.7.4' # should work with no version constraint once 0.8.2 is released https://github.com/httprb/http.rb/issues/203#issuecomment-100299898
|
32
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: syncano
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0.
|
4
|
+
version: 4.0.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Zadrożny
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-04-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -81,76 +81,6 @@ dependencies:
|
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0.8'
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
name: dirty_hashy
|
86
|
-
requirement: !ruby/object:Gem::Requirement
|
87
|
-
requirements:
|
88
|
-
- - "~>"
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: '0.2'
|
91
|
-
type: :runtime
|
92
|
-
prerelease: false
|
93
|
-
version_requirements: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
- - "~>"
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: '0.2'
|
98
|
-
- !ruby/object:Gem::Dependency
|
99
|
-
name: celluloid
|
100
|
-
requirement: !ruby/object:Gem::Requirement
|
101
|
-
requirements:
|
102
|
-
- - ">="
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
version: '0'
|
105
|
-
type: :runtime
|
106
|
-
prerelease: false
|
107
|
-
version_requirements: !ruby/object:Gem::Requirement
|
108
|
-
requirements:
|
109
|
-
- - ">="
|
110
|
-
- !ruby/object:Gem::Version
|
111
|
-
version: '0'
|
112
|
-
- !ruby/object:Gem::Dependency
|
113
|
-
name: celluloid-io
|
114
|
-
requirement: !ruby/object:Gem::Requirement
|
115
|
-
requirements:
|
116
|
-
- - ">="
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: '0'
|
119
|
-
type: :runtime
|
120
|
-
prerelease: false
|
121
|
-
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
requirements:
|
123
|
-
- - ">="
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: '0'
|
126
|
-
- !ruby/object:Gem::Dependency
|
127
|
-
name: mimetype-fu
|
128
|
-
requirement: !ruby/object:Gem::Requirement
|
129
|
-
requirements:
|
130
|
-
- - ">="
|
131
|
-
- !ruby/object:Gem::Version
|
132
|
-
version: '0'
|
133
|
-
type: :runtime
|
134
|
-
prerelease: false
|
135
|
-
version_requirements: !ruby/object:Gem::Requirement
|
136
|
-
requirements:
|
137
|
-
- - ">="
|
138
|
-
- !ruby/object:Gem::Version
|
139
|
-
version: '0'
|
140
|
-
- !ruby/object:Gem::Dependency
|
141
|
-
name: http
|
142
|
-
requirement: !ruby/object:Gem::Requirement
|
143
|
-
requirements:
|
144
|
-
- - '='
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
version: 0.7.4
|
147
|
-
type: :runtime
|
148
|
-
prerelease: false
|
149
|
-
version_requirements: !ruby/object:Gem::Requirement
|
150
|
-
requirements:
|
151
|
-
- - '='
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
version: 0.7.4
|
154
84
|
description: A Ruby client that provides convenient interface for the Syncano api.
|
155
85
|
email:
|
156
86
|
- piotr.zadrozny@mindpower.pl
|
@@ -168,25 +98,28 @@ files:
|
|
168
98
|
- README.md
|
169
99
|
- Rakefile
|
170
100
|
- circle.yml
|
101
|
+
- lib/active_attr/dirty.rb
|
102
|
+
- lib/active_attr/typecasting/hash_typecaster.rb
|
103
|
+
- lib/active_attr/typecasting_override.rb
|
171
104
|
- lib/syncano.rb
|
172
105
|
- lib/syncano/api.rb
|
173
|
-
- lib/syncano/api/endpoints.rb
|
174
106
|
- lib/syncano/connection.rb
|
175
|
-
- lib/syncano/
|
107
|
+
- lib/syncano/model/associations.rb
|
108
|
+
- lib/syncano/model/associations/base.rb
|
109
|
+
- lib/syncano/model/associations/belongs_to.rb
|
110
|
+
- lib/syncano/model/associations/has_many.rb
|
111
|
+
- lib/syncano/model/associations/has_one.rb
|
112
|
+
- lib/syncano/model/base.rb
|
113
|
+
- lib/syncano/model/callbacks.rb
|
114
|
+
- lib/syncano/model/scope_builder.rb
|
176
115
|
- lib/syncano/query_builder.rb
|
177
|
-
- lib/syncano/resources.rb
|
178
116
|
- lib/syncano/resources/base.rb
|
179
117
|
- lib/syncano/resources/collection.rb
|
180
|
-
- lib/syncano/resources/paths.rb
|
181
|
-
- lib/syncano/resources/resource_invalid.rb
|
182
118
|
- lib/syncano/resources/space.rb
|
183
|
-
- lib/syncano/response.rb
|
184
119
|
- lib/syncano/schema.rb
|
185
120
|
- lib/syncano/schema/attribute_definition.rb
|
186
|
-
- lib/syncano/schema/endpoints_whitelist.rb
|
187
121
|
- lib/syncano/schema/resource_definition.rb
|
188
122
|
- lib/syncano/scope.rb
|
189
|
-
- lib/syncano/upload_io.rb
|
190
123
|
- lib/syncano/version.rb
|
191
124
|
- spec/integration/syncano_spec.rb
|
192
125
|
- spec/spec_helper.rb
|
@@ -194,11 +127,8 @@ files:
|
|
194
127
|
- spec/unit/connection_spec.rb
|
195
128
|
- spec/unit/query_builder_spec.rb
|
196
129
|
- spec/unit/resources/collection_spec.rb
|
197
|
-
- spec/unit/resources/paths_spec.rb
|
198
130
|
- spec/unit/resources/space_spec.rb
|
199
131
|
- spec/unit/resources_base_spec.rb
|
200
|
-
- spec/unit/response_spec.rb
|
201
|
-
- spec/unit/schema/attribute_definition_spec.rb
|
202
132
|
- spec/unit/schema/resource_definition_spec.rb
|
203
133
|
- spec/unit/schema_spec.rb
|
204
134
|
- spec/unit/syncano_spec.rb
|
@@ -223,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
223
153
|
version: 1.3.1
|
224
154
|
requirements: []
|
225
155
|
rubyforge_project:
|
226
|
-
rubygems_version: 2.
|
156
|
+
rubygems_version: 2.2.2
|
227
157
|
signing_key:
|
228
158
|
specification_version: 4
|
229
159
|
summary: A Ruby client library for Syncano 4.0
|
@@ -234,11 +164,8 @@ test_files:
|
|
234
164
|
- spec/unit/connection_spec.rb
|
235
165
|
- spec/unit/query_builder_spec.rb
|
236
166
|
- spec/unit/resources/collection_spec.rb
|
237
|
-
- spec/unit/resources/paths_spec.rb
|
238
167
|
- spec/unit/resources/space_spec.rb
|
239
168
|
- spec/unit/resources_base_spec.rb
|
240
|
-
- spec/unit/response_spec.rb
|
241
|
-
- spec/unit/schema/attribute_definition_spec.rb
|
242
169
|
- spec/unit/schema/resource_definition_spec.rb
|
243
170
|
- spec/unit/schema_spec.rb
|
244
171
|
- spec/unit/syncano_spec.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Syncano
|
2
|
-
class API
|
3
|
-
module Endpoints
|
4
|
-
def self.definition(resources_definition)
|
5
|
-
Module.new do
|
6
|
-
resources_definition.each do |resource_definition|
|
7
|
-
resource_class = ::Syncano::Resources.define_resource_class(resource_definition)
|
8
|
-
|
9
|
-
define_method(resource_definition.name.tableize) do
|
10
|
-
::Syncano::QueryBuilder.new(connection, resource_class)
|
11
|
-
end if resource_definition.top_level?
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/lib/syncano/poller.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
module Syncano
|
2
|
-
class Poller
|
3
|
-
include Celluloid::IO
|
4
|
-
|
5
|
-
attr_accessor :connection, :method_name, :path, :responses
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(connection, method_name, path)
|
9
|
-
self.connection = connection
|
10
|
-
self.method_name = method_name
|
11
|
-
self.path = path
|
12
|
-
self.responses = []
|
13
|
-
end
|
14
|
-
|
15
|
-
def poll
|
16
|
-
loop do
|
17
|
-
responses << http_fetcher.get(path)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def last_response
|
22
|
-
responses.last
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def http_fetcher
|
28
|
-
HttpFetcher.new connection.api_key, connection.user_key
|
29
|
-
end
|
30
|
-
|
31
|
-
class HttpFetcher
|
32
|
-
attr_accessor :api_key, :user_key
|
33
|
-
|
34
|
-
def initialize(api_key, user_key)
|
35
|
-
self.api_key = api_key
|
36
|
-
self.user_key = user_key
|
37
|
-
end
|
38
|
-
|
39
|
-
def get(path, params = {})
|
40
|
-
url = Syncano::Connection.api_root + path
|
41
|
-
|
42
|
-
response = HTTP.
|
43
|
-
with_headers('X-API-KEY' => api_key,
|
44
|
-
'X-USER-KEY' => user_key,
|
45
|
-
'User-Agent' => "Syncano Ruby Gem #{Syncano::VERSION}").
|
46
|
-
get(url,
|
47
|
-
params: params,
|
48
|
-
ssl_socket_class: Celluloid::IO::SSLSocket,
|
49
|
-
socket_class: Celluloid::IO::TCPSocket)
|
50
|
-
|
51
|
-
response
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
data/lib/syncano/resources.rb
DELETED
@@ -1,158 +0,0 @@
|
|
1
|
-
require 'dirty_hashy'
|
2
|
-
|
3
|
-
module Syncano
|
4
|
-
module Resources
|
5
|
-
class << self
|
6
|
-
def build_definitions(schema_definition)
|
7
|
-
schema_definition.map do |name, raw_resource_definition|
|
8
|
-
::Syncano::Schema::ResourceDefinition.new(name, raw_resource_definition)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def define_resource_class(resource_definition)
|
13
|
-
resource_class = new_resource_class(resource_definition)
|
14
|
-
|
15
|
-
const_set resource_definition.name, resource_class
|
16
|
-
|
17
|
-
if resource_definition[:collection]
|
18
|
-
resources_paths.collections.define resource_definition[:collection][:path], resource_class
|
19
|
-
end
|
20
|
-
|
21
|
-
if resource_definition[:member]
|
22
|
-
resources_paths.members.define resource_definition[:member][:path], resource_class
|
23
|
-
end
|
24
|
-
|
25
|
-
resource_class
|
26
|
-
end
|
27
|
-
|
28
|
-
def resources_paths
|
29
|
-
::Syncano::Resources::Paths.instance
|
30
|
-
end
|
31
|
-
|
32
|
-
def new_resource_class(definition)
|
33
|
-
attributes_definitions = definition.attributes
|
34
|
-
|
35
|
-
::Class.new(::Syncano::Resources::Base) do
|
36
|
-
self.create_writable_attributes = []
|
37
|
-
self.update_writable_attributes = []
|
38
|
-
|
39
|
-
attributes_definitions.each do |attribute_definition|
|
40
|
-
|
41
|
-
attribute attribute_definition.name,
|
42
|
-
type: attribute_definition.type,
|
43
|
-
default: attribute_definition.default
|
44
|
-
|
45
|
-
# TODO extract to a dynamically defined module
|
46
|
-
define_method("#{attribute_definition.name}=") do |new_value|
|
47
|
-
if new_value != read_attribute(attribute_definition.name)
|
48
|
-
send("#{attribute_definition.name}_will_change!")
|
49
|
-
end
|
50
|
-
|
51
|
-
super new_value
|
52
|
-
end
|
53
|
-
|
54
|
-
if attribute_definition.validate?
|
55
|
-
validates attribute_definition.name, presence: true
|
56
|
-
end
|
57
|
-
|
58
|
-
validates attribute_definition.name, length: attribute_definition.required_length
|
59
|
-
|
60
|
-
if inclusion = attribute_definition.required_values_inclusion
|
61
|
-
validates attribute_definition.name, inclusion: inclusion
|
62
|
-
end
|
63
|
-
|
64
|
-
self.create_writable_attributes << attribute_definition.name.to_sym if attribute_definition.writable?
|
65
|
-
self.update_writable_attributes << attribute_definition.name.to_sym if attribute_definition.updatable?
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
if definition.name == 'Object' #TODO: extract to a separate module + spec
|
70
|
-
def save(options = {})
|
71
|
-
options.assert_valid_keys :overwrite
|
72
|
-
overwrite = options[:overwrite] == true
|
73
|
-
|
74
|
-
if new_record? || !overwrite
|
75
|
-
super()
|
76
|
-
else
|
77
|
-
response = connection.request(:post, member_path, attributes)
|
78
|
-
initialize! response, true
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def initialize!(_attributes = {}, _from_database = false)
|
83
|
-
to_return = super
|
84
|
-
|
85
|
-
custom_attributes.clean_up!
|
86
|
-
|
87
|
-
to_return
|
88
|
-
end
|
89
|
-
|
90
|
-
def select_changed_attributes
|
91
|
-
custom_attributes.changes.inject(super) do |changed, (key, (_was, is))|
|
92
|
-
changed[key] = is
|
93
|
-
changed
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def attributes=(new_attributes)
|
98
|
-
super
|
99
|
-
|
100
|
-
self.custom_attributes = new_attributes.select { |k, v| !self.class.attributes.keys.include?(k) }
|
101
|
-
end
|
102
|
-
|
103
|
-
def attributes
|
104
|
-
super.merge custom_attributes
|
105
|
-
end
|
106
|
-
|
107
|
-
def changed
|
108
|
-
super + custom_attributes.changes.keys
|
109
|
-
end
|
110
|
-
|
111
|
-
def custom_attributes
|
112
|
-
@custom_attributes ||= DirtyHashy.new
|
113
|
-
end
|
114
|
-
|
115
|
-
def custom_attributes=(value)
|
116
|
-
@custom_attributes = value.is_a?(DirtyHashy) ?
|
117
|
-
value : DirtyHashy.new(value)
|
118
|
-
end
|
119
|
-
|
120
|
-
def method_missing(method_name, *args, &block)
|
121
|
-
if method_name.to_s =~ /=$/
|
122
|
-
custom_attributes[method_name.to_s.gsub(/=$/, '')] = args.first
|
123
|
-
else
|
124
|
-
if custom_attributes.has_key? method_name.to_s
|
125
|
-
custom_attributes[method_name.to_s]
|
126
|
-
else
|
127
|
-
super
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
(definition[:associations]['links'] || []).each do |association_schema|
|
134
|
-
case association_schema['type']
|
135
|
-
when 'list'
|
136
|
-
define_method(association_schema['name']) do
|
137
|
-
has_many_association(association_schema['name'])
|
138
|
-
end
|
139
|
-
when 'run'
|
140
|
-
define_method(association_schema['name']) do |config = nil|
|
141
|
-
custom_method association_schema['name'], config
|
142
|
-
end
|
143
|
-
when 'poll'
|
144
|
-
define_method(association_schema['name']) do |config = nil|
|
145
|
-
async_method association_schema['name'], config
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
private
|
151
|
-
|
152
|
-
self.resource_definition = definition
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|