active_force 0.3.2 → 0.4.2
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/.travis.yml +0 -1
- data/README.md +17 -6
- data/active_force.gemspec +1 -1
- data/lib/active_force/active_query.rb +62 -0
- data/lib/active_force/association/has_many_association.rb +2 -18
- data/lib/active_force/query.rb +6 -2
- data/lib/active_force/sobject.rb +19 -43
- data/lib/active_force/version.rb +1 -1
- data/spec/active_force/active_query_spec.rb +38 -0
- data/spec/active_force/association_spec.rb +9 -7
- data/spec/{active_query → active_force}/query_spec.rb +0 -0
- data/spec/active_force/sobject_spec.rb +10 -3
- metadata +9 -5
- data/lib/active_force/finders.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2db05b88b32eacda2b94f3dcbc47a72288b1f4e4
|
4
|
+
data.tar.gz: 4c57fa4fa03fcb50d8378854b99377d6403206e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7629ee051094c5e4dbe73ee6c3c06fb31bbb1fa9cf5aea5705f661d5201dffa8eb9cc6d5fcc263e7ea90084f4bf30731749d206f2a8996a9c356cd876e4415ba
|
7
|
+
data.tar.gz: 21db5698eb4a8f6db16041cc70cd32a8d24520dc1655c7c6eb6bb3d2d1fa7d3b5e44c99e5ffbe93860c9bff2a19872edd5ceff8a20cdb8ee9d1512d103133223
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -23,7 +23,7 @@ And then execute:
|
|
23
23
|
Or install it yourself as:
|
24
24
|
|
25
25
|
$ gem install active_force
|
26
|
-
|
26
|
+
|
27
27
|
Rails:
|
28
28
|
|
29
29
|
```ruby
|
@@ -38,22 +38,33 @@ Restforce.log = true if Rails.env.development?
|
|
38
38
|
|
39
39
|
```ruby
|
40
40
|
class Page < ActiveForce::SObject
|
41
|
-
|
41
|
+
|
42
42
|
end
|
43
43
|
```
|
44
44
|
|
45
45
|
### Add Attributes
|
46
46
|
```ruby
|
47
47
|
class Page < ActiveForce::SObject
|
48
|
-
#field,
|
48
|
+
#field, :attribute_name, from: 'Name_In_Salesforce_Database'
|
49
49
|
field :id, from: 'Id'
|
50
|
-
field :name, from: 'Medication__c'
|
50
|
+
field :name, from: 'Medication__c'
|
51
51
|
self.fields = mappings.values
|
52
52
|
#set SalesForce table name.
|
53
53
|
self.table_name = 'Patient_Medication__c'
|
54
54
|
end
|
55
55
|
```
|
56
|
-
###
|
56
|
+
### Validations
|
57
|
+
You can use any validation that active record has (except for validates_associated), just by adding them to your class:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
validates :name, :login, :email, presence: true
|
61
|
+
validates :text, length: { minimum: 2 }
|
62
|
+
validates :text, format: { with: /\A[a-zA-Z]+\z/, message: "only allows letters" }
|
63
|
+
validates :size, inclusion: { in: %w(small medium large),
|
64
|
+
message: "%{value} is not a valid size" }
|
65
|
+
```
|
66
|
+
|
67
|
+
### Relationships
|
57
68
|
|
58
69
|
#### Has Many
|
59
70
|
|
@@ -73,7 +84,7 @@ you could send a option parameter in the declaration.
|
|
73
84
|
class Account < ActiveForce::SObject
|
74
85
|
has_many :medications,
|
75
86
|
where: "(Date_Discontinued__c > #{ Date.today.strftime("%Y-%m-%d") } or Date_Discontinued__c = NULL)"
|
76
|
-
|
87
|
+
|
77
88
|
has_many :today_log_entrys,
|
78
89
|
model: DailyLogEntry,
|
79
90
|
where: "Date__c = #{ Time.now.in_time_zone.strftime("%Y-%m-%d") }"
|
data/active_force.gemspec
CHANGED
@@ -6,7 +6,7 @@ require 'active_force/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "active_force"
|
8
8
|
spec.version = ActiveForce::VERSION
|
9
|
-
spec.authors = ["Eloy Espinaco", "Pablo Oldani"]
|
9
|
+
spec.authors = ["Eloy Espinaco", "Pablo Oldani", "Armando Andini", "José Piccioni"]
|
10
10
|
spec.email = "eloyesp@gmail.com"
|
11
11
|
spec.description = %q{Use SalesForce as an ActiveModel}
|
12
12
|
spec.summary = %q{Help you implement models persisting on Sales Force within Rails using RESTForce}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'active_force/query'
|
2
|
+
|
3
|
+
module ActiveForce
|
4
|
+
class ActiveQuery < Query
|
5
|
+
|
6
|
+
attr_reader :sobject
|
7
|
+
|
8
|
+
delegate :sfdc_client, :build, :table_name, :mappings, to: :sobject
|
9
|
+
|
10
|
+
def initialize sobject
|
11
|
+
@sobject = sobject
|
12
|
+
super table_name
|
13
|
+
fields sobject.fields
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_a
|
17
|
+
result.to_a.map do |mash|
|
18
|
+
build mash
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def count
|
23
|
+
super
|
24
|
+
sfdc_client.query(to_s).first.expr0
|
25
|
+
end
|
26
|
+
|
27
|
+
def all
|
28
|
+
to_a
|
29
|
+
end
|
30
|
+
|
31
|
+
def limit limit
|
32
|
+
super
|
33
|
+
limit == 1 ? to_a.first : self
|
34
|
+
end
|
35
|
+
|
36
|
+
def where conditions
|
37
|
+
return super unless conditions.is_a? Hash
|
38
|
+
conditions.each do |key, value|
|
39
|
+
super "#{ mappings[key] } = #{ enclose_value value }"
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_by conditions
|
45
|
+
where(conditions).limit 1
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def enclose_value value
|
51
|
+
if value.is_a? String
|
52
|
+
"'#{value}'"
|
53
|
+
else
|
54
|
+
value.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def result
|
59
|
+
sfdc_client.query(self.to_s)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -8,30 +8,14 @@ module ActiveForce
|
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
def
|
12
|
-
super
|
13
|
-
define_query_method
|
14
|
-
end
|
15
|
-
|
16
|
-
def define_query_method
|
11
|
+
def define_relation_method
|
17
12
|
association = self
|
18
|
-
@parent.send :define_method,
|
13
|
+
@parent.send :define_method, @relation_name do
|
19
14
|
query = association.relation_model.query
|
20
15
|
query.options association.options
|
21
16
|
query.where "#{ association.foreign_key } = '#{ self.id }'"
|
22
17
|
end
|
23
18
|
end
|
24
|
-
|
25
|
-
def define_relation_method
|
26
|
-
association = self
|
27
|
-
@parent.send :define_method, @relation_name do
|
28
|
-
association.relation_model.send_query send(association.query_method_name)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def query_method_name
|
33
|
-
"#{ @relation_name }_query"
|
34
|
-
end
|
35
19
|
end
|
36
20
|
end
|
37
21
|
end
|
data/lib/active_force/query.rb
CHANGED
@@ -10,7 +10,7 @@ module ActiveForce
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def fields fields_collection = []
|
13
|
-
@query_fields
|
13
|
+
@query_fields += fields_collection.to_a
|
14
14
|
end
|
15
15
|
|
16
16
|
def all
|
@@ -20,7 +20,7 @@ module ActiveForce
|
|
20
20
|
def to_s
|
21
21
|
<<-SOQL.gsub(/\s+/, " ").strip
|
22
22
|
SELECT
|
23
|
-
#{
|
23
|
+
#{ build_select }
|
24
24
|
FROM
|
25
25
|
#{ @table }
|
26
26
|
#{ build_where }
|
@@ -88,6 +88,10 @@ module ActiveForce
|
|
88
88
|
end
|
89
89
|
|
90
90
|
protected
|
91
|
+
def build_select
|
92
|
+
@query_fields.uniq.join(', ')
|
93
|
+
end
|
94
|
+
|
91
95
|
def build_where
|
92
96
|
"WHERE #{ @conditions.join(' AND ') }" unless @conditions.empty?
|
93
97
|
end
|
data/lib/active_force/sobject.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'active_model'
|
2
2
|
require 'active_attr'
|
3
3
|
require 'active_attr/dirty'
|
4
|
-
require 'active_force/
|
4
|
+
require 'active_force/active_query'
|
5
5
|
require 'active_force/association'
|
6
|
-
require 'active_force/finders'
|
7
6
|
require 'yaml'
|
8
7
|
|
9
8
|
module ActiveForce
|
@@ -11,62 +10,33 @@ module ActiveForce
|
|
11
10
|
include ActiveAttr::Model
|
12
11
|
include ActiveAttr::Dirty
|
13
12
|
include ActiveForce::Association
|
14
|
-
include ActiveForce::Finders
|
15
13
|
|
16
14
|
STANDARD_TYPES = %w[ Account Contact Opportunity Campaign]
|
17
15
|
|
18
16
|
class_attribute :mappings, :fields, :table_name
|
19
17
|
|
18
|
+
class << self
|
19
|
+
delegate :where, :first, :last, :all, :find, :find_by, :count, :to => :query
|
20
|
+
end
|
21
|
+
|
20
22
|
# The table name to used to make queries.
|
21
23
|
# It is derived from the class name adding the "__c" when needed.
|
22
24
|
def self.table_name
|
23
|
-
@table_name ||=
|
24
|
-
self.name
|
25
|
-
else
|
26
|
-
"#{self.name}__c"
|
27
|
-
end
|
25
|
+
@table_name ||= custom_table_name || "#{ self.name }__c"
|
28
26
|
end
|
29
27
|
|
30
|
-
def self.build
|
31
|
-
return unless
|
32
|
-
|
28
|
+
def self.build sf_table_description
|
29
|
+
return unless sf_table_description
|
30
|
+
sobject = new
|
33
31
|
mappings.each do |attr, sf_field|
|
34
|
-
|
32
|
+
sobject[attr] = sf_table_description[sf_field]
|
35
33
|
end
|
36
|
-
|
37
|
-
|
34
|
+
sobject.changed_attributes.clear
|
35
|
+
sobject
|
38
36
|
end
|
39
37
|
|
40
38
|
def self.query
|
41
|
-
|
42
|
-
query.fields fields
|
43
|
-
query
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.first
|
47
|
-
send_query(query.first).first
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.last
|
51
|
-
send_query(query.last).first
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.all
|
55
|
-
send_query query
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.count
|
59
|
-
sfdc_client.query(query.count).first.expr0
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.send_query query
|
63
|
-
sfdc_client.query(query.to_s).to_a.map do |mash|
|
64
|
-
build mash
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.find id
|
69
|
-
send_query(query.find(id)).first
|
39
|
+
ActiveForce::ActiveQuery.new self
|
70
40
|
end
|
71
41
|
|
72
42
|
def update_attributes! attributes = {}
|
@@ -139,7 +109,13 @@ module ActiveForce
|
|
139
109
|
@mappings ||= {}
|
140
110
|
end
|
141
111
|
|
112
|
+
|
142
113
|
private
|
114
|
+
|
115
|
+
def self.custom_table_name
|
116
|
+
self.name if STANDARD_TYPES.include? self.name
|
117
|
+
end
|
118
|
+
|
143
119
|
def read_value field
|
144
120
|
if self.class.attributes[field][:sf_type] == :multi_picklist
|
145
121
|
attribute(field.to_s).reject(&:empty?).join(';')
|
data/lib/active_force/version.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_force/active_query'
|
3
|
+
|
4
|
+
describe ActiveForce::ActiveQuery do
|
5
|
+
let(:sobject){
|
6
|
+
sobject = double("sobject")
|
7
|
+
sobject.stub(:table_name).and_return "table_name"
|
8
|
+
sobject.stub(:fields).and_return []
|
9
|
+
sobject
|
10
|
+
}
|
11
|
+
|
12
|
+
let(:client){
|
13
|
+
double("client")
|
14
|
+
}
|
15
|
+
|
16
|
+
before do
|
17
|
+
@active_query = ActiveForce::ActiveQuery.new(sobject)
|
18
|
+
@active_query.stub(:sfdc_client).and_return client
|
19
|
+
@active_query.stub(:build).and_return Object.new
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "to_a" do
|
23
|
+
before do
|
24
|
+
expect(client).to receive(:query)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return an array of objects" do
|
28
|
+
result = @active_query.where("Text_Label = 'foo'").to_a
|
29
|
+
expect(result).to be_a Array
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should allow to chain query methods" do
|
33
|
+
result = @active_query.where("Text_Label = 'foo'").where("Checkbox_Label = true").to_a
|
34
|
+
expect(result).to be_a Array
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -44,44 +44,46 @@ describe ActiveForce::SObject do
|
|
44
44
|
expect(post).to respond_to(:comments)
|
45
45
|
end
|
46
46
|
|
47
|
-
it "should return a
|
48
|
-
post.
|
47
|
+
it "should return a ActiveQuery object" do
|
48
|
+
expect(post.comments).to be_a ActiveForce::ActiveQuery
|
49
49
|
end
|
50
50
|
|
51
51
|
describe 'to_s' do
|
52
52
|
it "should retrun a OSQL statment" do
|
53
|
-
post.
|
53
|
+
post.comments.to_s.should ==
|
54
54
|
"SELECT Id FROM Comment__c WHERE Post__c = '1'"
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
57
58
|
end
|
58
59
|
|
59
60
|
describe 'has_many(options)' do
|
60
61
|
|
61
62
|
it 'should allow to send a different query table name' do
|
62
63
|
Post.has_many :ugly_comments, { model: Comment }
|
63
|
-
post.
|
64
|
+
post.comments.to_s.should ==
|
64
65
|
"SELECT Id FROM Comment__c WHERE Post__c = '1'"
|
65
66
|
end
|
66
67
|
|
67
68
|
it 'should allow to change the foreign key' do
|
68
69
|
Post.has_many :comments, { foreign_key: 'Post' }
|
69
|
-
post.
|
70
|
+
post.comments.to_s.should ==
|
70
71
|
"SELECT Id FROM Comment__c WHERE Post = '1'"
|
71
72
|
end
|
72
73
|
|
73
74
|
it 'should allow to add a where condition' do
|
74
75
|
Post.has_many :comments, { where: '1 = 1' }
|
75
|
-
post.
|
76
|
+
post.comments.to_s.should ==
|
76
77
|
"SELECT Id FROM Comment__c WHERE 1 = 1 AND Post__c = '1'"
|
77
78
|
end
|
78
79
|
|
79
80
|
it 'should use a convention name for the foreign key' do
|
80
81
|
Comment.field :post_id, from: 'PostId'
|
81
82
|
Post.has_many :comments
|
82
|
-
post.
|
83
|
+
post.comments.to_s.should ==
|
83
84
|
"SELECT Id FROM Comment__c WHERE PostId = '1'"
|
84
85
|
end
|
86
|
+
|
85
87
|
end
|
86
88
|
|
87
89
|
describe "belongs_to" do
|
File without changes
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ActiveForce::SObject do
|
4
|
+
let(:sobject_hash) { YAML.load(fixture('sobject/single_sobject_hash')) }
|
4
5
|
|
5
6
|
before do
|
6
7
|
::Client = double('Client')
|
@@ -18,7 +19,6 @@ describe ActiveForce::SObject do
|
|
18
19
|
end
|
19
20
|
|
20
21
|
describe ".build" do
|
21
|
-
let(:sobject_hash) { YAML.load(fixture('sobject/single_sobject_hash')) }
|
22
22
|
|
23
23
|
it "build a valid sobject from a JSON" do
|
24
24
|
expect(Whizbang.build sobject_hash).to be_an_instance_of Whizbang
|
@@ -72,19 +72,26 @@ describe ActiveForce::SObject do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
it "sends the query to the client" do
|
75
|
-
Client.
|
75
|
+
expect(Client).to receive(:query).and_return(count_response)
|
76
76
|
expect(Whizbang.count).to eq(1)
|
77
77
|
end
|
78
78
|
|
79
79
|
end
|
80
80
|
|
81
|
+
# describe "first" do
|
82
|
+
# it "should return the first value" do
|
83
|
+
# binding.pry
|
84
|
+
# expect(Whizbang.first).to eq(1)
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
|
81
88
|
describe "#find_by" do
|
82
89
|
it "responds to find_by" do
|
83
90
|
Whizbang.should respond_to(:find_by)
|
84
91
|
end
|
85
92
|
|
86
93
|
it "should query the client, with the SFDC field names and correctly enclosed values" do
|
87
|
-
Client.should_receive(:query).with("SELECT Id FROM Whizbang__c WHERE Id = 123 AND Text_Label = 'foo'")
|
94
|
+
Client.should_receive(:query).with("SELECT Id FROM Whizbang__c WHERE Id = 123 AND Text_Label = 'foo' LIMIT 1")
|
88
95
|
Whizbang.find_by id: 123, text: "foo"
|
89
96
|
end
|
90
97
|
end
|
metadata
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_force
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eloy Espinaco
|
8
8
|
- Pablo Oldani
|
9
|
+
- Armando Andini
|
10
|
+
- José Piccioni
|
9
11
|
autorequire:
|
10
12
|
bindir: bin
|
11
13
|
cert_chain: []
|
12
|
-
date: 2014-08-
|
14
|
+
date: 2014-08-15 00:00:00.000000000 Z
|
13
15
|
dependencies:
|
14
16
|
- !ruby/object:Gem::Dependency
|
15
17
|
name: active_attr
|
@@ -112,22 +114,23 @@ files:
|
|
112
114
|
- active_force.gemspec
|
113
115
|
- lib/active_attr/dirty.rb
|
114
116
|
- lib/active_force.rb
|
117
|
+
- lib/active_force/active_query.rb
|
115
118
|
- lib/active_force/association.rb
|
116
119
|
- lib/active_force/association/association.rb
|
117
120
|
- lib/active_force/association/belongs_to_association.rb
|
118
121
|
- lib/active_force/association/has_many_association.rb
|
119
|
-
- lib/active_force/finders.rb
|
120
122
|
- lib/active_force/query.rb
|
121
123
|
- lib/active_force/sobject.rb
|
122
124
|
- lib/active_force/version.rb
|
123
125
|
- lib/generators/active_force/active_force_model/USAGE
|
124
126
|
- lib/generators/active_force/active_force_model/active_force_model_generator.rb
|
125
127
|
- lib/generators/active_force/active_force_model/templates/model.rb.erb
|
128
|
+
- spec/active_force/active_query_spec.rb
|
126
129
|
- spec/active_force/association_spec.rb
|
130
|
+
- spec/active_force/query_spec.rb
|
127
131
|
- spec/active_force/sobject/table_name_spec.rb
|
128
132
|
- spec/active_force/sobject_spec.rb
|
129
133
|
- spec/active_force_spec.rb
|
130
|
-
- spec/active_query/query_spec.rb
|
131
134
|
- spec/fixtures/sobject/single_sobject_hash.yml
|
132
135
|
- spec/spec_helper.rb
|
133
136
|
- spec/support/fixture_helpers.rb
|
@@ -157,11 +160,12 @@ signing_key:
|
|
157
160
|
specification_version: 4
|
158
161
|
summary: Help you implement models persisting on Sales Force within Rails using RESTForce
|
159
162
|
test_files:
|
163
|
+
- spec/active_force/active_query_spec.rb
|
160
164
|
- spec/active_force/association_spec.rb
|
165
|
+
- spec/active_force/query_spec.rb
|
161
166
|
- spec/active_force/sobject/table_name_spec.rb
|
162
167
|
- spec/active_force/sobject_spec.rb
|
163
168
|
- spec/active_force_spec.rb
|
164
|
-
- spec/active_query/query_spec.rb
|
165
169
|
- spec/fixtures/sobject/single_sobject_hash.yml
|
166
170
|
- spec/spec_helper.rb
|
167
171
|
- spec/support/fixture_helpers.rb
|
data/lib/active_force/finders.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
module ActiveForce
|
2
|
-
module Finders
|
3
|
-
module ClassMethods
|
4
|
-
def find_by conditions
|
5
|
-
query = self.query
|
6
|
-
query_conditions(conditions).each do |query_condition|
|
7
|
-
query = query.where query_condition
|
8
|
-
end
|
9
|
-
send_query(query).first
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
#maps a hash key => value to a string 'key = value'
|
15
|
-
def query_conditions conditions
|
16
|
-
conditions.map do |key, value|
|
17
|
-
"#{ mappings[key] } = #{ enclose_value value }"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# encloses the value in quotes if it's a string
|
22
|
-
def enclose_value value
|
23
|
-
if value.is_a? String
|
24
|
-
"'#{value}'"
|
25
|
-
else
|
26
|
-
value.to_s
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.included mod
|
33
|
-
mod.extend ClassMethods
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|