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
data/lib/active_force/table.rb
CHANGED
@@ -7,18 +7,22 @@ module ActiveForce
|
|
7
7
|
@klass = klass.to_s
|
8
8
|
end
|
9
9
|
|
10
|
+
def table_name name = nil
|
11
|
+
@name = name || @name || pick_table_name
|
12
|
+
end
|
13
|
+
|
10
14
|
def name
|
11
15
|
@name ||= pick_table_name
|
12
16
|
end
|
13
17
|
|
14
|
-
def
|
18
|
+
def custom_table?
|
15
19
|
!StandardTypes::STANDARD_TYPES.include?(name_without_namespace)
|
16
20
|
end
|
17
21
|
|
18
22
|
private
|
19
23
|
|
20
24
|
def pick_table_name
|
21
|
-
if
|
25
|
+
if custom_table?
|
22
26
|
"#{ name_without_namespace }__c"
|
23
27
|
else
|
24
28
|
name_without_namespace
|
data/lib/active_force/version.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_force/active_query'
|
3
2
|
|
4
3
|
describe ActiveForce::ActiveQuery do
|
5
4
|
let(:sobject) do
|
@@ -44,17 +43,22 @@ describe ActiveForce::ActiveQuery do
|
|
44
43
|
describe "condition mapping" do
|
45
44
|
it "maps conditions for a .where" do
|
46
45
|
active_query.where(field: 123)
|
47
|
-
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE Field__c = 123")
|
46
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c = 123)")
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'transforms an array to a WHERE/IN clause' do
|
50
|
+
active_query.where(field: ['foo', 'bar'])
|
51
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c IN ('foo','bar'))")
|
48
52
|
end
|
49
53
|
|
50
54
|
it "encloses the value in quotes if it's a string" do
|
51
55
|
active_query.where field: "hello"
|
52
|
-
expect(active_query.to_s).to end_with("Field__c = 'hello'")
|
56
|
+
expect(active_query.to_s).to end_with("(Field__c = 'hello')")
|
53
57
|
end
|
54
58
|
|
55
59
|
it "puts NULL when a field is set as nil" do
|
56
60
|
active_query.where field: nil
|
57
|
-
expect(active_query.to_s).to end_with("Field__c = NULL")
|
61
|
+
expect(active_query.to_s).to end_with("(Field__c = NULL)")
|
58
62
|
end
|
59
63
|
|
60
64
|
describe 'bind parameters' do
|
@@ -67,17 +71,17 @@ describe ActiveForce::ActiveQuery do
|
|
67
71
|
|
68
72
|
it 'accepts bind parameters' do
|
69
73
|
active_query.where('Field__c = ?', 123)
|
70
|
-
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE Field__c = 123")
|
74
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c = 123)")
|
71
75
|
end
|
72
76
|
|
73
77
|
it 'accepts nil bind parameters' do
|
74
78
|
active_query.where('Field__c = ?', nil)
|
75
|
-
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE Field__c = NULL")
|
79
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c = NULL)")
|
76
80
|
end
|
77
81
|
|
78
82
|
it 'accepts multiple bind parameters' do
|
79
83
|
active_query.where('Field__c = ? AND Other_Field__c = ? AND Name = ?', 123, 321, 'Bob')
|
80
|
-
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE Field__c = 123 AND Other_Field__c = 321 AND Name = 'Bob'")
|
84
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c = 123 AND Other_Field__c = 321 AND Name = 'Bob')")
|
81
85
|
end
|
82
86
|
|
83
87
|
it 'complains when there given an incorrect number of bind parameters' do
|
@@ -89,22 +93,22 @@ describe ActiveForce::ActiveQuery do
|
|
89
93
|
context 'named bind parameters' do
|
90
94
|
it 'accepts bind parameters' do
|
91
95
|
active_query.where('Field__c = :field', field: 123)
|
92
|
-
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE Field__c = 123")
|
96
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c = 123)")
|
93
97
|
end
|
94
98
|
|
95
99
|
it 'accepts nil bind parameters' do
|
96
100
|
active_query.where('Field__c = :field', field: nil)
|
97
|
-
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE Field__c = NULL")
|
101
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c = NULL)")
|
98
102
|
end
|
99
103
|
|
100
104
|
it 'accepts multiple bind parameters' do
|
101
105
|
active_query.where('Field__c = :field AND Other_Field__c = :other_field AND Name = :name', field: 123, other_field: 321, name: 'Bob')
|
102
|
-
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE Field__c = 123 AND Other_Field__c = 321 AND Name = 'Bob'")
|
106
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c = 123 AND Other_Field__c = 321 AND Name = 'Bob')")
|
103
107
|
end
|
104
108
|
|
105
109
|
it 'accepts multiple bind parameters orderless' do
|
106
110
|
active_query.where('Field__c = :field AND Other_Field__c = :other_field AND Name = :name', name: 'Bob', other_field: 321, field: 123)
|
107
|
-
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE Field__c = 123 AND Other_Field__c = 321 AND Name = 'Bob'")
|
111
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Field__c = 123 AND Other_Field__c = 321 AND Name = 'Bob')")
|
108
112
|
end
|
109
113
|
|
110
114
|
it 'complains when there given an incorrect number of bind parameters' do
|
@@ -120,7 +124,7 @@ describe ActiveForce::ActiveQuery do
|
|
120
124
|
it "should query the client, with the SFDC field names and correctly enclosed values" do
|
121
125
|
expect(client).to receive :query
|
122
126
|
active_query.find_by field: 123
|
123
|
-
expect(active_query.to_s).to eq "SELECT Id FROM table_name WHERE Field__c = 123 LIMIT 1"
|
127
|
+
expect(active_query.to_s).to eq "SELECT Id FROM table_name WHERE (Field__c = 123) LIMIT 1"
|
124
128
|
end
|
125
129
|
end
|
126
130
|
|
@@ -137,4 +141,27 @@ describe ActiveForce::ActiveQuery do
|
|
137
141
|
active_query.map {}
|
138
142
|
end
|
139
143
|
end
|
144
|
+
|
145
|
+
describe "prevent SOQL injection attacks" do
|
146
|
+
let(:mappings){ { quote_field: "QuoteField", backslash_field: "Backslash_Field__c", number_field: "NumberField" } }
|
147
|
+
let(:quote_input){ "' OR Id!=NULL OR Id='" }
|
148
|
+
let(:backslash_input){ "\\" }
|
149
|
+
let(:number_input){ 123 }
|
150
|
+
let(:expected_query){ "SELECT Id FROM table_name WHERE (Backslash_Field__c = '\\\\' AND NumberField = 123 AND QuoteField = ''' OR Id!=NULL OR Id=''')" }
|
151
|
+
|
152
|
+
it 'escapes quotes and backslashes in bind parameters' do
|
153
|
+
active_query.where('Backslash_Field__c = :backslash_field AND NumberField = :number_field AND QuoteField = :quote_field', number_field: number_input, backslash_field: backslash_input, quote_field: quote_input)
|
154
|
+
expect(active_query.to_s).to eq(expected_query)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'escapes quotes and backslashes in named bind parameters' do
|
158
|
+
active_query.where('Backslash_Field__c = ? AND NumberField = ? AND QuoteField = ?', backslash_input, number_input, quote_input)
|
159
|
+
expect(active_query.to_s).to eq(expected_query)
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'escapes quotes and backslashes in hash conditions' do
|
163
|
+
active_query.where(backslash_field: backslash_input, number_field: number_input, quote_field: quote_input)
|
164
|
+
expect(active_query.to_s).to eq("SELECT Id FROM table_name WHERE (Backslash_Field__c = '\\\\') AND (NumberField = 123) AND (QuoteField = ''' OR Id!=NULL OR Id=''')")
|
165
|
+
end
|
166
|
+
end
|
140
167
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ActiveForce
|
4
|
+
module Association
|
5
|
+
describe RelationModelBuilder do
|
6
|
+
let(:instance){ described_class.new association, value }
|
7
|
+
|
8
|
+
describe '#build_relation_model' do
|
9
|
+
context 'has_many' do
|
10
|
+
let(:association){ HasManyAssociation.new Post, :comments }
|
11
|
+
|
12
|
+
context 'with values' do
|
13
|
+
let(:value) do
|
14
|
+
build_restforce_collection([
|
15
|
+
Restforce::SObject.new({'Id' => '213', 'PostId' => '123'}),
|
16
|
+
Restforce::SObject.new({'Id' => '214', 'PostId' => '123'})
|
17
|
+
])
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns an array of Comments' do
|
21
|
+
comments = instance.build_relation_model
|
22
|
+
expect(comments).to be_a Array
|
23
|
+
expect(comments.all?{ |c| c.is_a? Comment }).to be true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'without values' do
|
28
|
+
let(:value){ nil }
|
29
|
+
|
30
|
+
it 'returns an empty array' do
|
31
|
+
comments = instance.build_relation_model
|
32
|
+
expect(comments).to be_a Array
|
33
|
+
expect(comments).to be_empty
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'belongs_to' do
|
39
|
+
let(:association){ BelongsToAssociation.new(Comment, :post) }
|
40
|
+
|
41
|
+
context 'with a value' do
|
42
|
+
let(:value) do
|
43
|
+
build_restforce_sobject 'Id' => '213'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns a post' do
|
47
|
+
expect(instance.build_relation_model).to be_a Post
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'without a value' do
|
52
|
+
let(:value){ nil }
|
53
|
+
|
54
|
+
it 'returns nil' do
|
55
|
+
expect(instance.build_relation_model).to be_nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_force/association'
|
3
2
|
|
4
3
|
describe ActiveForce::SObject do
|
5
|
-
|
6
4
|
let :post do
|
7
|
-
Post.new(id: "1")
|
5
|
+
Post.new(id: "1", title: 'Ham')
|
8
6
|
end
|
9
7
|
|
10
8
|
let :comment do
|
@@ -12,29 +10,14 @@ describe ActiveForce::SObject do
|
|
12
10
|
end
|
13
11
|
|
14
12
|
let :client do
|
15
|
-
double("sfdc_client", query: [Restforce::Mash.new(
|
13
|
+
double("sfdc_client", query: [Restforce::Mash.new("Id" => 1)])
|
16
14
|
end
|
17
15
|
|
18
16
|
before do
|
19
|
-
class Post < ActiveForce::SObject
|
20
|
-
self.table_name = "Post__c"
|
21
|
-
end
|
22
|
-
|
23
|
-
class Comment < ActiveForce::SObject
|
24
|
-
field :post_id, from: "PostId"
|
25
|
-
self.table_name = "Comment__c"
|
26
|
-
end
|
27
|
-
|
28
17
|
allow(ActiveForce::SObject).to receive(:sfdc_client).and_return client
|
29
18
|
end
|
30
19
|
|
31
20
|
describe "has_many_query" do
|
32
|
-
before do
|
33
|
-
class Post < ActiveForce::SObject
|
34
|
-
has_many :comments
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
21
|
it "should respond to relation method" do
|
39
22
|
expect(post).to respond_to(:comments)
|
40
23
|
end
|
@@ -51,7 +34,7 @@ describe ActiveForce::SObject do
|
|
51
34
|
|
52
35
|
describe 'to_s' do
|
53
36
|
it "should return a SOQL statment" do
|
54
|
-
soql = "SELECT Id, PostId FROM Comment__c WHERE PostId = '1'"
|
37
|
+
soql = "SELECT Id, PostId, PosterId__c, FancyPostId, Body__c FROM Comment__c WHERE (PostId = '1')"
|
55
38
|
expect(post.comments.to_s).to eq soql
|
56
39
|
end
|
57
40
|
end
|
@@ -59,80 +42,62 @@ describe ActiveForce::SObject do
|
|
59
42
|
context 'when the SObject is namespaced' do
|
60
43
|
let(:account){ Foo::Account.new(id: '1') }
|
61
44
|
|
62
|
-
before do
|
63
|
-
module Foo
|
64
|
-
class Opportunity < ActiveForce::SObject
|
65
|
-
field :account_id, from: 'AccountId'
|
66
|
-
end
|
67
|
-
|
68
|
-
class Account < ActiveForce::SObject
|
69
|
-
has_many :opportunities, model: Foo::Opportunity
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
45
|
it 'correctly infers the foreign key and forms the correct query' do
|
75
|
-
soql = "SELECT Id, AccountId FROM Opportunity WHERE AccountId = '1'"
|
46
|
+
soql = "SELECT Id, AccountId, Partner_Account_Id__c FROM Opportunity WHERE (AccountId = '1')"
|
76
47
|
expect(account.opportunities.to_s).to eq soql
|
77
48
|
end
|
78
49
|
|
79
50
|
it 'uses an explicit foreign key if it is supplied' do
|
80
|
-
|
81
|
-
|
82
|
-
soql = "SELECT Id, AccountId, Partner_Account_Id__c FROM Opportunity WHERE Partner_Account_Id__c = '1'"
|
83
|
-
expect(account.opportunities.to_s).to eq soql
|
51
|
+
soql = "SELECT Id, AccountId, Partner_Account_Id__c FROM Opportunity WHERE (Partner_Account_Id__c = '1')"
|
52
|
+
expect(account.partner_opportunities.to_s).to eq soql
|
84
53
|
end
|
85
54
|
end
|
86
55
|
end
|
87
56
|
|
88
57
|
describe 'has_many(options)' do
|
89
|
-
before do
|
90
|
-
Post.has_many :comments
|
91
|
-
end
|
92
|
-
|
93
58
|
it 'should allow to send a different query table name' do
|
94
|
-
|
95
|
-
soql = "SELECT Id, PostId FROM Comment__c WHERE PostId = '1'"
|
59
|
+
soql = "SELECT Id, PostId, PosterId__c, FancyPostId, Body__c FROM Comment__c WHERE (PostId = '1')"
|
96
60
|
expect(post.ugly_comments.to_s).to eq soql
|
97
61
|
end
|
98
62
|
|
99
63
|
it 'should allow to change the foreign key' do
|
100
|
-
|
101
|
-
|
102
|
-
soql = "SELECT Id, PostId FROM Comment__c WHERE PostId = '1'"
|
103
|
-
expect(post.comments.to_s).to eq soql
|
64
|
+
soql = "SELECT Id, PostId, PosterId__c, FancyPostId, Body__c FROM Comment__c WHERE (PosterId__c = '1')"
|
65
|
+
expect(post.poster_comments.to_s).to eq soql
|
104
66
|
end
|
105
67
|
|
106
68
|
it 'should allow to add a where condition' do
|
107
|
-
|
108
|
-
|
109
|
-
|
69
|
+
soql = "SELECT Id, PostId, PosterId__c, FancyPostId, Body__c FROM Comment__c WHERE (1 = 0) AND (PostId = '1')"
|
70
|
+
expect(post.impossible_comments.to_s).to eq soql
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'accepts custom scoping' do
|
74
|
+
soql = "SELECT Id, PostId, PosterId__c, FancyPostId, Body__c FROM Comment__c WHERE (Body__c = 'RE: Ham') AND (PostId = '1') ORDER BY CreationDate DESC"
|
75
|
+
expect(post.reply_comments.to_s).to eq soql
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'accepts custom scoping that preloads associations of the association' do
|
79
|
+
account = Salesforce::Account.new id: '1', business_partner: 'qwerty'
|
80
|
+
soql = "SELECT Id, OwnerId, AccountId, Business_Partner__c, Owner.Id FROM Opportunity WHERE (Business_Partner__c = 'qwerty') AND (AccountId = '1')"
|
81
|
+
expect(account.partner_opportunities.to_s).to eq soql
|
110
82
|
end
|
111
83
|
|
112
84
|
it 'should use a convention name for the foreign key' do
|
113
|
-
soql = "SELECT Id, PostId FROM Comment__c WHERE PostId = '1'"
|
85
|
+
soql = "SELECT Id, PostId, PosterId__c, FancyPostId, Body__c FROM Comment__c WHERE (PostId = '1')"
|
114
86
|
expect(post.comments.to_s).to eq soql
|
115
87
|
end
|
116
|
-
|
117
88
|
end
|
118
89
|
|
119
90
|
describe "belongs_to" do
|
120
|
-
before do
|
121
|
-
Comment.belongs_to :post
|
122
|
-
end
|
123
|
-
|
124
91
|
it "should get the resource it belongs to" do
|
125
92
|
expect(comment.post).to be_instance_of(Post)
|
126
93
|
end
|
127
94
|
|
128
95
|
it "should allow to pass a foreign key as options" do
|
129
|
-
|
130
|
-
field :fancy_post_id, from: 'PostId'
|
131
|
-
belongs_to :post, foreign_key: :fancy_post_id
|
132
|
-
end
|
96
|
+
Comment.belongs_to :post, foreign_key: :fancy_post_id
|
133
97
|
allow(comment).to receive(:fancy_post_id).and_return "2"
|
134
|
-
expect(client).to receive(:query).with("SELECT Id FROM Post__c WHERE Id = '2' LIMIT 1")
|
98
|
+
expect(client).to receive(:query).with("SELECT Id, Title__c FROM Post__c WHERE (Id = '2') LIMIT 1")
|
135
99
|
comment.post
|
100
|
+
Comment.belongs_to :post # reset association to original value
|
136
101
|
end
|
137
102
|
|
138
103
|
it 'makes only one API call to fetch the associated object' do
|
@@ -141,29 +106,37 @@ describe ActiveForce::SObject do
|
|
141
106
|
comment.post
|
142
107
|
end
|
143
108
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
109
|
+
describe "assignments" do
|
110
|
+
let(:comment) do
|
111
|
+
comment = Comment.new(id: '1')
|
112
|
+
comment.post = Post.new(id: '1')
|
113
|
+
comment
|
114
|
+
end
|
151
115
|
|
152
|
-
context 'when the SObject is namespaced' do
|
153
|
-
let(:attachment){ Foo::Attachment.new(id: '1', lead_id: '2') }
|
154
116
|
before do
|
155
|
-
|
156
|
-
|
117
|
+
expect(client).to_not receive(:query)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'accepts assignment of an existing object as an association' do
|
121
|
+
expect(client).to_not receive(:query)
|
122
|
+
other_post = Post.new(id: "2")
|
123
|
+
comment.post = other_post
|
124
|
+
expect(comment.post_id).to eq other_post.id
|
125
|
+
expect(comment.post).to eq other_post
|
126
|
+
end
|
157
127
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
end
|
128
|
+
it 'can desassociate an object by setting it as nil' do
|
129
|
+
comment.post = nil
|
130
|
+
expect(comment.post_id).to eq nil
|
131
|
+
expect(comment.post).to eq nil
|
163
132
|
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when the SObject is namespaced' do
|
136
|
+
let(:attachment){ Foo::Attachment.new(id: '1', lead_id: '2') }
|
164
137
|
|
165
138
|
it 'generates the correct query' do
|
166
|
-
expect(client).to receive(:query).with("SELECT Id FROM Lead WHERE Id = '2' LIMIT 1")
|
139
|
+
expect(client).to receive(:query).with("SELECT Id FROM Lead WHERE (Id = '2') LIMIT 1")
|
167
140
|
attachment.lead
|
168
141
|
end
|
169
142
|
|
@@ -173,18 +146,10 @@ describe ActiveForce::SObject do
|
|
173
146
|
|
174
147
|
context 'when given a foreign key' do
|
175
148
|
let(:attachment){ Foo::Attachment.new(id: '1', fancy_lead_id: '2') }
|
176
|
-
before do
|
177
|
-
module Foo
|
178
|
-
class Attachment < ActiveForce::SObject
|
179
|
-
field :fancy_lead_id, from: 'LeadId'
|
180
|
-
belongs_to :lead, model: Foo::Lead, foreign_key: :fancy_lead_id
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
149
|
|
185
150
|
it 'generates the correct query' do
|
186
|
-
expect(client).to receive(:query).with("SELECT Id FROM Lead WHERE Id = '2' LIMIT 1")
|
187
|
-
attachment.
|
151
|
+
expect(client).to receive(:query).with("SELECT Id FROM Lead WHERE (Id = '2') LIMIT 1")
|
152
|
+
attachment.fancy_lead
|
188
153
|
end
|
189
154
|
end
|
190
155
|
end
|