active_force 0.6.1 → 0.7.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/CHANGELOG.md +7 -0
- data/README.md +43 -17
- data/lib/active_attr/dirty.rb +3 -0
- data/lib/active_force/active_query.rb +32 -2
- data/lib/active_force/association.rb +14 -10
- data/lib/active_force/association/association.rb +26 -11
- data/lib/active_force/association/belongs_to_association.rb +1 -4
- data/lib/active_force/association/eager_load_projection_builder.rb +60 -0
- data/lib/active_force/association/has_many_association.rb +15 -5
- data/lib/active_force/association/relation_model_builder.rb +70 -0
- data/lib/active_force/attribute.rb +30 -0
- data/lib/active_force/mapping.rb +78 -0
- data/lib/active_force/query.rb +2 -8
- data/lib/active_force/sobject.rb +79 -95
- data/lib/active_force/table.rb +6 -2
- data/lib/active_force/version.rb +1 -1
- data/lib/generators/active_force/model/model_generator.rb +1 -0
- data/lib/generators/active_force/model/templates/model.rb.erb +0 -2
- data/spec/active_force/active_query_spec.rb +39 -12
- data/spec/active_force/association/relation_model_builder_spec.rb +62 -0
- data/spec/active_force/association_spec.rb +53 -88
- data/spec/active_force/attribute_spec.rb +27 -0
- data/spec/active_force/callbacks_spec.rb +1 -23
- data/spec/active_force/mapping_spec.rb +18 -0
- data/spec/active_force/query_spec.rb +32 -54
- data/spec/active_force/sobject/includes_spec.rb +290 -0
- data/spec/active_force/sobject/table_name_spec.rb +0 -21
- data/spec/active_force/sobject_spec.rb +212 -29
- data/spec/active_force/table_spec.rb +0 -3
- data/spec/fixtures/sobject/single_sobject_hash.yml +2 -0
- data/spec/spec_helper.rb +10 -4
- data/spec/support/restforce_factories.rb +9 -0
- data/spec/support/sobjects.rb +97 -0
- data/spec/support/whizbang.rb +25 -7
- metadata +18 -2
@@ -2,45 +2,24 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ActiveForce::SObject do
|
4
4
|
describe '#table_name' do
|
5
|
-
|
6
5
|
it 'Use the class name adding "__c"' do
|
7
|
-
class Custom < ActiveForce::SObject
|
8
|
-
end
|
9
|
-
|
10
6
|
expect(Custom.table_name).to eq('Custom__c')
|
11
7
|
end
|
12
8
|
|
13
9
|
it 'with standard SObject types it does not add the "__c"' do
|
14
|
-
class Account < ActiveForce::SObject
|
15
|
-
end
|
16
|
-
|
17
10
|
expect(Account.table_name).to eq('Account')
|
18
11
|
end
|
19
12
|
|
20
13
|
it 'can be enforced in the class definition' do
|
21
|
-
class EnforcedTableName < ActiveForce::SObject
|
22
|
-
self.table_name = 'Forced__c'
|
23
|
-
end
|
24
|
-
|
25
14
|
expect(EnforcedTableName.table_name).to eq('Forced__c')
|
26
15
|
end
|
27
16
|
|
28
17
|
context 'with a namespace' do
|
29
18
|
it "the namespace is not included" do
|
30
|
-
module Foo
|
31
|
-
class Bar < ActiveForce::SObject
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
19
|
expect(Foo::Bar.table_name).to eq('Bar__c')
|
36
20
|
end
|
37
21
|
|
38
22
|
it 'standard types are inferred correctly' do
|
39
|
-
module Foo
|
40
|
-
class Account < ActiveForce::SObject
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
23
|
expect(Foo::Account.table_name).to eq('Account')
|
45
24
|
end
|
46
25
|
end
|
@@ -9,17 +9,26 @@ describe ActiveForce::SObject do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe ".new" do
|
12
|
-
|
13
12
|
it 'should assigns values when are passed by parameters' do
|
14
13
|
expect(Whizbang.new({ text: 'some text' }).text).to eq 'some text'
|
15
14
|
end
|
16
|
-
|
17
15
|
end
|
18
16
|
|
19
17
|
describe ".build" do
|
18
|
+
let(:sobject){ Whizbang.build sobject_hash }
|
20
19
|
|
21
20
|
it "build a valid sobject from a JSON" do
|
22
|
-
expect(
|
21
|
+
expect(sobject).to be_an_instance_of Whizbang
|
22
|
+
end
|
23
|
+
|
24
|
+
it "sets the values' types from the sf_type" do
|
25
|
+
expect(sobject.boolean).to be_an_instance_of TrueClass
|
26
|
+
expect(sobject.checkbox).to be_an_instance_of FalseClass
|
27
|
+
expect(sobject.date).to be_an_instance_of Date
|
28
|
+
expect(sobject.datetime).to be_an_instance_of DateTime
|
29
|
+
expect(sobject.percent).to be_an_instance_of Float
|
30
|
+
expect(sobject.text).to be_an_instance_of String
|
31
|
+
expect(sobject.picklist_multiselect).to be_an_instance_of String
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
@@ -61,6 +70,7 @@ describe ActiveForce::SObject do
|
|
61
70
|
class IceCream < ActiveForce::SObject
|
62
71
|
field :flavors, as: :multi_picklist
|
63
72
|
end
|
73
|
+
sundae.changed_attributes.clear
|
64
74
|
sundae.flavors = %w(chocolate vanilla strawberry)
|
65
75
|
end
|
66
76
|
|
@@ -84,53 +94,143 @@ describe ActiveForce::SObject do
|
|
84
94
|
end
|
85
95
|
|
86
96
|
describe "CRUD" do
|
87
|
-
|
88
|
-
Whizbang.new(id: '1')
|
89
|
-
end
|
97
|
+
let(:instance){ Whizbang.new(id: '1') }
|
90
98
|
|
91
99
|
describe '#update' do
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
100
|
+
|
101
|
+
context 'with valid attributes' do
|
102
|
+
before do
|
103
|
+
expected_args = [
|
104
|
+
Whizbang.table_name,
|
105
|
+
{'Text_Label' => 'some text', 'Boolean_Label' => false, 'Id' => '1', "Updated_From__c"=>"Rails"}
|
106
|
+
]
|
107
|
+
expect(client).to receive(:update!).with(*expected_args).and_return('id')
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'delegates to the Client with create! and sets the id' do
|
111
|
+
expect(instance.update( text: 'some text', boolean: false )).to eq(true)
|
112
|
+
expect(instance.text).to eq('some text')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'with invalid attributes' do
|
117
|
+
it 'sets the error on the instance' do
|
118
|
+
expect(instance.update( boolean: true )).to eq(false)
|
119
|
+
expect(instance.errors).to be_present
|
120
|
+
expect(instance.errors.full_messages.count).to eq(1)
|
121
|
+
expect(instance.errors.full_messages[0]).to eq("Percent can't be blank")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe ".update!" do
|
127
|
+
context 'with valid attributes' do
|
128
|
+
describe 'and without a ClientError' do
|
129
|
+
before do
|
130
|
+
expected_args = [
|
131
|
+
Whizbang.table_name,
|
132
|
+
{'Text_Label' => 'some text', 'Boolean_Label' => false, 'Id' => '1', "Updated_From__c"=>"Rails"}
|
133
|
+
]
|
134
|
+
expect(client).to receive(:update!).with(*expected_args).and_return('id')
|
135
|
+
end
|
136
|
+
it 'saves successfully' do
|
137
|
+
expect(instance.update!( text: 'some text', boolean: false )).to eq(true)
|
138
|
+
expect(instance.text).to eq('some text')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe 'and with a ClientError' do
|
143
|
+
let(:faraday_error){ Faraday::Error::ClientError.new('Some String') }
|
144
|
+
|
145
|
+
before{ expect(client).to receive(:update!).and_raise(faraday_error) }
|
146
|
+
|
147
|
+
it 'raises an error' do
|
148
|
+
expect{ instance.update!( text: 'some text', boolean: false ) }.to raise_error(Faraday::Error::ClientError)
|
149
|
+
end
|
150
|
+
end
|
98
151
|
end
|
99
152
|
|
100
|
-
|
101
|
-
|
153
|
+
context 'with invalid attributes' do
|
154
|
+
let(:instance){ Whizbang.new boolean: true }
|
155
|
+
|
156
|
+
it 'raises an error' do
|
157
|
+
expect{ instance.update!( text: 'some text', boolean: true ) }.to raise_error(ActiveForce::RecordInvalid)
|
158
|
+
end
|
102
159
|
end
|
103
160
|
end
|
104
161
|
|
105
162
|
describe '#create' do
|
106
|
-
|
107
|
-
|
163
|
+
context 'with valid attributes' do
|
164
|
+
before do
|
165
|
+
expect(client).to receive(:create!).and_return('id')
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'delegates to the Client with create! and sets the id' do
|
169
|
+
expect(instance.create).to be_instance_of(Whizbang)
|
170
|
+
expect(instance.id).to eq('id')
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
context 'with invalid attributes' do
|
176
|
+
let(:instance){ Whizbang.new boolean: true }
|
177
|
+
|
178
|
+
it 'sets the error on the instance' do
|
179
|
+
expect(instance.create).to be_instance_of(Whizbang)
|
180
|
+
expect(instance.id).to eq(nil)
|
181
|
+
expect(instance.errors).to be_present
|
182
|
+
expect(instance.errors.full_messages.count).to eq(1)
|
183
|
+
expect(instance.errors.full_messages[0]).to eq("Percent can't be blank")
|
184
|
+
end
|
108
185
|
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe '#create!' do
|
189
|
+
context 'with valid attributes' do
|
190
|
+
describe 'and without a ClientError' do
|
191
|
+
|
192
|
+
before{ expect(client).to receive(:create!).and_return('id') }
|
109
193
|
|
110
|
-
|
111
|
-
|
194
|
+
it 'saves successfully' do
|
195
|
+
expect(instance.create!).to be_instance_of(Whizbang)
|
196
|
+
expect(instance.id).to eq('id')
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe 'and with a ClientError' do
|
201
|
+
let(:faraday_error){ Faraday::Error::ClientError.new('Some String') }
|
202
|
+
|
203
|
+
before{ expect(client).to receive(:create!).and_raise(faraday_error) }
|
204
|
+
|
205
|
+
it 'raises an error' do
|
206
|
+
expect{ instance.create! }.to raise_error(Faraday::Error::ClientError)
|
207
|
+
end
|
208
|
+
end
|
112
209
|
end
|
113
210
|
|
114
|
-
|
115
|
-
|
116
|
-
|
211
|
+
context 'with invalid attributes' do
|
212
|
+
let(:instance){ Whizbang.new boolean: true }
|
213
|
+
|
214
|
+
it 'raises an error' do
|
215
|
+
expect{ instance.create! }.to raise_error(ActiveForce::RecordInvalid)
|
216
|
+
end
|
117
217
|
end
|
118
218
|
end
|
119
219
|
|
120
220
|
describe "#destroy" do
|
121
221
|
it "should send client :destroy! with its id" do
|
122
222
|
expect(client).to receive(:destroy!).with 'Whizbang__c', '1'
|
123
|
-
|
223
|
+
instance.destroy
|
124
224
|
end
|
125
225
|
end
|
126
226
|
|
127
227
|
describe 'self.create' do
|
128
228
|
before do
|
129
|
-
expect(client).to receive(:create!).with(Whizbang.table_name, 'Text_Label' => 'some text').and_return('id')
|
229
|
+
expect(client).to receive(:create!).with(Whizbang.table_name, 'Text_Label' => 'some text', 'Updated_From__c'=>'Rails').and_return('id')
|
130
230
|
end
|
131
231
|
|
132
232
|
it 'should create a new instance' do
|
133
|
-
expect(Whizbang.create(
|
233
|
+
expect(Whizbang.create(text: 'some text')).to be_instance_of(Whizbang)
|
134
234
|
end
|
135
235
|
end
|
136
236
|
end
|
@@ -151,7 +251,7 @@ describe ActiveForce::SObject do
|
|
151
251
|
|
152
252
|
describe "#find_by" do
|
153
253
|
it "should query the client, with the SFDC field names and correctly enclosed values" do
|
154
|
-
expect(client).to receive(:query).with("SELECT #{Whizbang.fields.join ', '} FROM Whizbang__c WHERE Id = 123 AND Text_Label = 'foo' LIMIT 1")
|
254
|
+
expect(client).to receive(:query).with("SELECT #{Whizbang.fields.join ', '} FROM Whizbang__c WHERE (Id = 123) AND (Text_Label = 'foo') LIMIT 1")
|
155
255
|
Whizbang.find_by id: 123, text: "foo"
|
156
256
|
end
|
157
257
|
end
|
@@ -164,13 +264,11 @@ describe ActiveForce::SObject do
|
|
164
264
|
let(:territory){ Territory.new(id: '1', quota_id: '1') }
|
165
265
|
|
166
266
|
before do
|
167
|
-
Territory.belongs_to :quota, model: Quota
|
168
|
-
Territory.field :quota_id, from: 'Quota_Id'
|
169
267
|
allow(ActiveForce::SObject).to receive(:sfdc_client).and_return client
|
170
268
|
end
|
171
269
|
|
172
270
|
it 'clears cached associations' do
|
173
|
-
soql = "SELECT Id, Bar_Id__c FROM Quota__c WHERE Id = '1' LIMIT 1"
|
271
|
+
soql = "SELECT Id, Bar_Id__c FROM Quota__c WHERE (Id = '1') LIMIT 1"
|
174
272
|
expect(client).to receive(:query).twice.with soql
|
175
273
|
allow(Territory).to receive(:find){ territory }
|
176
274
|
territory.quota
|
@@ -180,7 +278,6 @@ describe ActiveForce::SObject do
|
|
180
278
|
end
|
181
279
|
|
182
280
|
it "refreshes the object's attributes" do
|
183
|
-
Territory.field :name, from: 'Name'
|
184
281
|
territory.name = 'Walter'
|
185
282
|
expect(territory.name).to eq 'Walter'
|
186
283
|
territory.reload
|
@@ -212,4 +309,90 @@ describe ActiveForce::SObject do
|
|
212
309
|
end
|
213
310
|
end
|
214
311
|
end
|
312
|
+
|
313
|
+
describe 'logger output' do
|
314
|
+
let(:instance){ Whizbang.new }
|
315
|
+
|
316
|
+
before do
|
317
|
+
allow(instance).to receive(:create!).and_raise(Faraday::Error::ClientError.new(double))
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'catches and logs the error' do
|
321
|
+
expect(instance).to receive(:logger_output).and_return(false)
|
322
|
+
instance.save
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
describe ".save!" do
|
327
|
+
let(:instance){ Whizbang.new }
|
328
|
+
|
329
|
+
context 'with valid attributes' do
|
330
|
+
describe 'and without a ClientError' do
|
331
|
+
before{ expect(client).to receive(:create!).and_return('id') }
|
332
|
+
it 'saves successfully' do
|
333
|
+
expect(instance.save!).to eq(true)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe 'and with a ClientError' do
|
338
|
+
let(:faraday_error){ Faraday::Error::ClientError.new('Some String') }
|
339
|
+
|
340
|
+
before{ expect(client).to receive(:create!).and_raise(faraday_error) }
|
341
|
+
|
342
|
+
it 'raises an error' do
|
343
|
+
expect{ instance.save! }.to raise_error(Faraday::Error::ClientError)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
context 'with invalid attributes' do
|
349
|
+
let(:instance){ Whizbang.new boolean: true }
|
350
|
+
|
351
|
+
it 'raises an error' do
|
352
|
+
expect{ instance.save! }.to raise_error(ActiveForce::RecordInvalid)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
describe ".save" do
|
358
|
+
let(:instance){ Whizbang.new }
|
359
|
+
|
360
|
+
context 'with valid attributes' do
|
361
|
+
describe 'and without a ClientError' do
|
362
|
+
before{ expect(client).to receive(:create!).and_return('id') }
|
363
|
+
it 'saves successfully' do
|
364
|
+
expect(instance.save).to eq(true)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
describe 'and with a ClientError' do
|
369
|
+
let(:faraday_error){ Faraday::Error::ClientError.new('Some String') }
|
370
|
+
before{ expect(client).to receive(:create!).and_raise(faraday_error) }
|
371
|
+
it 'returns false' do
|
372
|
+
expect(instance.save).to eq(false)
|
373
|
+
end
|
374
|
+
it 'sets the error on the instance' do
|
375
|
+
instance.save
|
376
|
+
expect(instance.errors).to be_present
|
377
|
+
expect(instance.errors.full_messages.count).to eq(1)
|
378
|
+
expect(instance.errors.full_messages[0]).to eq('Some String')
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
context 'with invalid attributes' do
|
384
|
+
let(:instance){ Whizbang.new boolean: true }
|
385
|
+
|
386
|
+
it 'does not save' do
|
387
|
+
expect(instance.save).to eq(false)
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'sets the error on the instance' do
|
391
|
+
instance.save
|
392
|
+
expect(instance.errors).to be_present
|
393
|
+
expect(instance.errors.full_messages.count).to eq(1)
|
394
|
+
expect(instance.errors.full_messages[0]).to eq("Percent can't be blank")
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
215
398
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_force/table'
|
3
2
|
|
4
3
|
describe ActiveForce::Table do
|
5
4
|
describe '#table_name' do
|
6
|
-
|
7
5
|
let(:table) { ActiveForce::Table }
|
8
6
|
|
9
7
|
it 'Use the class name adding "__c"' do
|
@@ -23,6 +21,5 @@ describe ActiveForce::Table do
|
|
23
21
|
expect(table.new('Foo::Account').name).to eq('Account')
|
24
22
|
end
|
25
23
|
end
|
26
|
-
|
27
24
|
end
|
28
25
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,12 +2,18 @@ require "codeclimate-test-reporter"
|
|
2
2
|
CodeClimate::TestReporter.start
|
3
3
|
|
4
4
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
5
|
-
require 'restforce'
|
6
5
|
require 'active_force'
|
7
6
|
Dir["./spec/support/**/*"].sort.each { |f| require f }
|
8
7
|
require 'pry'
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
10
|
+
inflect.plural 'quota', 'quotas'
|
11
|
+
inflect.plural 'Quota', 'Quotas'
|
12
|
+
inflect.singular 'quota', 'quota'
|
13
|
+
inflect.singular 'Quota', 'Quota'
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.order = :random
|
18
|
+
config.include RestforceFactories
|
13
19
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
|
2
|
+
class Comment < ActiveForce::SObject
|
3
|
+
self.table_name = "Comment__c"
|
4
|
+
field :post_id, from: "PostId"
|
5
|
+
field :poster_id, from: 'PosterId__c'
|
6
|
+
field :fancy_post_id, from: 'FancyPostId'
|
7
|
+
field :body
|
8
|
+
belongs_to :post
|
9
|
+
end
|
10
|
+
class Post < ActiveForce::SObject
|
11
|
+
self.table_name = "Post__c"
|
12
|
+
field :title
|
13
|
+
has_many :comments
|
14
|
+
has_many :impossible_comments, model: Comment, scoped_as: ->{ where('1 = 0') }
|
15
|
+
has_many :reply_comments, model: Comment, scoped_as: ->(post){ where(body: "RE: #{post.title}").order('CreationDate DESC') }
|
16
|
+
has_many :ugly_comments, { model: Comment }
|
17
|
+
has_many :poster_comments, { foreign_key: :poster_id, model: Comment }
|
18
|
+
end
|
19
|
+
class Territory < ActiveForce::SObject
|
20
|
+
field :quota_id, from: "Quota__c"
|
21
|
+
field :name, from: 'Name'
|
22
|
+
belongs_to :quota
|
23
|
+
end
|
24
|
+
class PrezClub < ActiveForce::SObject
|
25
|
+
field :quota_id, from: 'QuotaId'
|
26
|
+
belongs_to :quota
|
27
|
+
end
|
28
|
+
class Quota < ActiveForce::SObject
|
29
|
+
field :id, from: 'Bar_Id__c'
|
30
|
+
has_many :prez_clubs
|
31
|
+
has_many :territories
|
32
|
+
end
|
33
|
+
class Opportunity < ActiveForce::SObject
|
34
|
+
field :account_id, from: 'AccountId'
|
35
|
+
belongs_to :account
|
36
|
+
end
|
37
|
+
class Account < ActiveForce::SObject
|
38
|
+
field :owner_id, from: 'OwnerId'
|
39
|
+
has_many :opportunities
|
40
|
+
belongs_to :owner
|
41
|
+
end
|
42
|
+
class Owner < ActiveForce::SObject
|
43
|
+
has_many :accounts
|
44
|
+
end
|
45
|
+
class Custom < ActiveForce::SObject; end
|
46
|
+
class EnforcedTableName < ActiveForce::SObject
|
47
|
+
self.table_name = 'Forced__c'
|
48
|
+
end
|
49
|
+
|
50
|
+
module Foo
|
51
|
+
class Bar < ActiveForce::SObject; end
|
52
|
+
class Opportunity < ActiveForce::SObject
|
53
|
+
field :account_id, from: 'AccountId'
|
54
|
+
field :partner_account_id, from: 'Partner_Account_Id__c'
|
55
|
+
end
|
56
|
+
class Account < ActiveForce::SObject
|
57
|
+
has_many :opportunities, model: Foo::Opportunity
|
58
|
+
has_many :partner_opportunities, foreign_key: :partner_account_id, model: Foo::Opportunity
|
59
|
+
end
|
60
|
+
class Lead < ActiveForce::SObject; end
|
61
|
+
class Attachment < ActiveForce::SObject
|
62
|
+
field :lead_id, from: 'Lead_Id__c'
|
63
|
+
field :fancy_lead_id, from: 'LeadId'
|
64
|
+
belongs_to :lead, model: Foo::Lead
|
65
|
+
belongs_to :fancy_lead, model: Foo::Lead, foreign_key: :fancy_lead_id
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module Salesforce
|
70
|
+
class PrezClub < ActiveForce::SObject
|
71
|
+
field :quota_id, from: 'QuotaId'
|
72
|
+
end
|
73
|
+
class Quota < ActiveForce::SObject
|
74
|
+
has_many :prez_clubs, model: PrezClub
|
75
|
+
end
|
76
|
+
class Widget < ActiveForce::SObject
|
77
|
+
self.table_name = 'Tegdiw__c'
|
78
|
+
end
|
79
|
+
class Territory < ActiveForce::SObject
|
80
|
+
field :quota_id, from: "QuotaId"
|
81
|
+
field :widget_id, from: 'WidgetId'
|
82
|
+
belongs_to :quota, model: Salesforce::Quota, foreign_key: :quota_id
|
83
|
+
belongs_to :widget, model: Salesforce::Widget, foreign_key: :widget_id
|
84
|
+
end
|
85
|
+
class User < ActiveForce::SObject
|
86
|
+
end
|
87
|
+
class Opportunity < ActiveForce::SObject
|
88
|
+
field :owner_id, from: 'OwnerId'
|
89
|
+
field :account_id, from: 'AccountId'
|
90
|
+
field :business_partner
|
91
|
+
belongs_to :owner, model: Salesforce::User, foreign_key: :owner_id, relationship_name: 'Owner'
|
92
|
+
end
|
93
|
+
class Account < ActiveForce::SObject
|
94
|
+
field :business_partner
|
95
|
+
has_many :partner_opportunities, model: Opportunity, scoped_as: ->(account){ where(business_partner: account.business_partner).includes(:owner) }
|
96
|
+
end
|
97
|
+
end
|