active_force 0.7.1 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/config.yml +107 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +24 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.mailmap +3 -0
- data/CHANGELOG.md +115 -42
- data/CODEOWNERS +2 -0
- data/Gemfile +0 -1
- data/README.md +100 -21
- data/active_force.gemspec +11 -4
- data/lib/active_force/active_query.rb +107 -6
- data/lib/active_force/association/association.rb +47 -3
- data/lib/active_force/association/belongs_to_association.rb +25 -11
- data/lib/active_force/association/eager_load_projection_builder.rb +9 -3
- data/lib/active_force/association/has_many_association.rb +19 -19
- data/lib/active_force/association/has_one_association.rb +30 -0
- data/lib/active_force/association/relation_model_builder.rb +1 -1
- data/lib/active_force/association.rb +6 -4
- data/lib/active_force/{attribute.rb → field.rb} +3 -3
- data/lib/active_force/mapping.rb +6 -32
- data/lib/active_force/query.rb +21 -2
- data/lib/active_force/sobject.rb +74 -28
- data/lib/active_force/version.rb +3 -1
- data/lib/active_force.rb +2 -0
- data/lib/active_model/type/salesforce/multipicklist.rb +29 -0
- data/lib/active_model/type/salesforce/percent.rb +22 -0
- data/lib/generators/active_force/model/model_generator.rb +32 -21
- data/lib/generators/active_force/model/templates/model.rb.erb +3 -1
- data/spec/active_force/active_query_spec.rb +200 -8
- data/spec/active_force/association/relation_model_builder_spec.rb +22 -0
- data/spec/active_force/association_spec.rb +252 -9
- data/spec/active_force/field_spec.rb +34 -0
- data/spec/active_force/query_spec.rb +26 -0
- data/spec/active_force/sobject/includes_spec.rb +10 -10
- data/spec/active_force/sobject_spec.rb +221 -14
- data/spec/fixtures/sobject/single_sobject_hash.yml +1 -1
- data/spec/spec_helper.rb +5 -2
- data/spec/support/bangwhiz.rb +7 -0
- data/spec/support/restforce_factories.rb +1 -1
- data/spec/support/sobjects.rb +17 -1
- data/spec/support/whizbang.rb +2 -2
- metadata +64 -26
- data/lib/active_attr/dirty.rb +0 -24
- data/spec/active_force/attribute_spec.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 661e75020c19d46986c8556c2e39799831468741b96909bab00f40d3ffb1294c
|
4
|
+
data.tar.gz: c2549061250e05f2f145c3129c4f83c1d973b09097c77e03592b68b892f54e02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bb66f6e4278cc3552200adef1cf4bff72ee01681253b573aa28fb1f8f410bb09a836c043b0b9dc1f1df744167050a03c8ca538f0a1cbc025645ca6ebe90a6ef
|
7
|
+
data.tar.gz: e5e52a99e28c971a1fe7e4a7135031bfa15cbeeadb1c782a1252915ba593699bda99b0f1a6f832c673d129cdc10ed2527ecff391144c4db30783af87bd40090b
|
@@ -0,0 +1,107 @@
|
|
1
|
+
version: 2
|
2
|
+
|
3
|
+
references:
|
4
|
+
default_docker_ruby_executor: &default_docker_ruby_executor
|
5
|
+
image: cimg/ruby:2.7.7
|
6
|
+
environment:
|
7
|
+
BUNDLE_PATH: vendor/bundle
|
8
|
+
RAILS_ENV: test
|
9
|
+
COVERAGE: true
|
10
|
+
TZ: /usr/share/zoneinfo/America/Chicago
|
11
|
+
CC_TEST_REPORTER_ID: bd3425becf01f0b46ac11dd33e1e935d65d89f55051c087bfa035e0f89b290a2
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
build:
|
15
|
+
working_directory: ~/active_force/active_force_index
|
16
|
+
docker:
|
17
|
+
- *default_docker_ruby_executor
|
18
|
+
steps:
|
19
|
+
- checkout
|
20
|
+
- restore_cache:
|
21
|
+
keys:
|
22
|
+
- active_force-{{ checksum "active_force.gemspec" }}
|
23
|
+
- active_force-
|
24
|
+
- run:
|
25
|
+
name: Bundle Install
|
26
|
+
command: |
|
27
|
+
gem install bundler
|
28
|
+
bundle check || bundle install
|
29
|
+
- save_cache:
|
30
|
+
key: active_force-{{ checksum "active_force.gemspec" }}
|
31
|
+
paths:
|
32
|
+
- ~/active_force/active_force_index/vendor/bundle
|
33
|
+
|
34
|
+
rspec-test:
|
35
|
+
working_directory: ~/active_force/active_force_index
|
36
|
+
parallelism: 1
|
37
|
+
docker:
|
38
|
+
- *default_docker_ruby_executor
|
39
|
+
steps:
|
40
|
+
- checkout
|
41
|
+
- restore_cache:
|
42
|
+
keys:
|
43
|
+
- active_force-{{ checksum "active_force.gemspec" }}
|
44
|
+
- active_force-
|
45
|
+
- run:
|
46
|
+
name: Bundle Install
|
47
|
+
command: |
|
48
|
+
gem install bundler
|
49
|
+
bundle check || bundle install
|
50
|
+
- save_cache:
|
51
|
+
key: active_force-{{ checksum "active_force.gemspec" }}
|
52
|
+
paths:
|
53
|
+
- ~/active_force/active_force_index/vendor/bundle
|
54
|
+
- run:
|
55
|
+
name: Install Code Climate Test Reporter
|
56
|
+
command: |
|
57
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
58
|
+
chmod +x ./cc-test-reporter
|
59
|
+
- run:
|
60
|
+
name: Run RSpec
|
61
|
+
command: |
|
62
|
+
mkdir /tmp/test-results
|
63
|
+
./cc-test-reporter before-build
|
64
|
+
TESTFILES=$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
|
65
|
+
bundle exec rspec $TESTFILES --profile 10 --format RspecJunitFormatter --out /tmp/test-results/rspec.xml --format progress
|
66
|
+
- run:
|
67
|
+
name: Code Climate Test Coverage
|
68
|
+
command: |
|
69
|
+
./cc-test-reporter format-coverage -t simplecov -o "coverage/codeclimate.$CIRCLE_NODE_INDEX.json"
|
70
|
+
- persist_to_workspace:
|
71
|
+
root: coverage
|
72
|
+
paths:
|
73
|
+
- codeclimate.*.json
|
74
|
+
- store_test_results:
|
75
|
+
path: /tmp/test-results
|
76
|
+
- store_artifacts:
|
77
|
+
path: /tmp/test-results
|
78
|
+
destination: test-results
|
79
|
+
- store_artifacts:
|
80
|
+
path: coverage
|
81
|
+
upload-coverage:
|
82
|
+
working_directory: ~/active_force/active_force_index
|
83
|
+
docker:
|
84
|
+
- *default_docker_ruby_executor
|
85
|
+
steps:
|
86
|
+
- attach_workspace:
|
87
|
+
at: ~/active_force/active_force_index
|
88
|
+
- run:
|
89
|
+
name: Install Code Climate Test Reporter
|
90
|
+
command: |
|
91
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
92
|
+
chmod +x ./cc-test-reporter
|
93
|
+
- run:
|
94
|
+
name: Combine and Upload Coverage
|
95
|
+
command: |
|
96
|
+
./cc-test-reporter sum-coverage --output - codeclimate.*.json | ./cc-test-reporter upload-coverage --debug --input -
|
97
|
+
workflows:
|
98
|
+
version: 2
|
99
|
+
build_and_test:
|
100
|
+
jobs:
|
101
|
+
- build
|
102
|
+
- rspec-test:
|
103
|
+
requires:
|
104
|
+
- build
|
105
|
+
- upload-coverage:
|
106
|
+
requires:
|
107
|
+
- rspec-test
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
name: Bug report
|
3
|
+
about: Create a report to help us improve
|
4
|
+
title: "[BUG]"
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Describe the bug**
|
11
|
+
A clear and concise description of what the bug is.
|
12
|
+
|
13
|
+
**To Reproduce**
|
14
|
+
Steps to reproduce the behavior:
|
15
|
+
1. Go to '...'
|
16
|
+
2. Click on '....'
|
17
|
+
3. Scroll down to '....'
|
18
|
+
4. See error
|
19
|
+
|
20
|
+
**Expected behavior**
|
21
|
+
A clear and concise description of what you expected to happen.
|
22
|
+
|
23
|
+
**Additional context**
|
24
|
+
Add any other context about the problem here.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
name: Feature request
|
3
|
+
about: Suggest an idea for this project
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
12
|
+
|
13
|
+
**Describe the solution you'd like**
|
14
|
+
A clear and concise description of what you want to happen.
|
15
|
+
|
16
|
+
**Describe alternatives you've considered**
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
18
|
+
|
19
|
+
**Additional context**
|
20
|
+
Add any other context or screenshots about the feature request here.
|
data/.mailmap
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,78 +1,151 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
3
|
## Not released
|
4
|
+
## 0.15.0
|
5
|
+
- Fix model defaults so data is persisted in Salesforce (https://github.com/Beyond-Finance/active_force/pull/55)
|
6
|
+
- Add `pluck` query method (https://github.com/Beyond-Finance/active_force/pull/51)
|
7
|
+
- Add `#order` method to active query that accepts arguments in several formats ( symbol, string that has raw soql) (https://github.com/Beyond-Finance/active_force/pull/58)
|
8
|
+
|
9
|
+
|
10
|
+
## 0.14.0
|
11
|
+
|
12
|
+
- Add `scoped_as` option to `has_one` association (https://github.com/Beyond-Finance/active_force/pull/50)
|
13
|
+
- Add `default` to model fields (https://github.com/Beyond-Finance/active_force/pull/49)
|
14
|
+
- Allow `nil` datetimes as `:datetime` fields (https://github.com/Beyond-Finance/active_force/pull/52)
|
15
|
+
|
16
|
+
## 0.13.2
|
17
|
+
- Add `#loaded?` method for ActiveQueries to allow the detection of records loaded in memory or pending to be loaded. (https://github.com/Beyond-Finance/active_force/pull/45)
|
18
|
+
- Use attributes' values_for_database (serialize) value instead of using the type casted value to allow more flexibility when creating your own ActiveModel type
|
19
|
+
|
20
|
+
## 0.13.1
|
21
|
+
|
22
|
+
- Fix constructor of `ActiveForce::RecordNotFound` (https://github.com/Beyond-Finance/active_force/pull/44)
|
23
|
+
- Add `.to_json` and `.as_json` to `SObject` to allow JSON serialization (https://github.com/Beyond-Finance/active_force/pull/37)
|
24
|
+
- Memoize the `ActiveForce::Mapping#mappings` Hash since it is based on the fields and those are generally only set when the class is loaded. Also use `Hash#key` which returns the key for a value rather than `Hash#invert` which creates a new Hash with key/value inverted. (https://github.com/Beyond-Finance/active_force/pull/41)
|
25
|
+
|
26
|
+
## 0.13.0
|
27
|
+
|
28
|
+
- Add `.find!` to `SObject` (https://github.com/Beyond-Finance/active_force/pull/39)
|
29
|
+
|
30
|
+
## 0.12.0
|
31
|
+
|
32
|
+
- Add `.describe` to `SObject` to allow convenient metadata fetching (https://github.com/Beyond-Finance/active_force/pull/36)
|
33
|
+
|
34
|
+
## 0.11.4
|
35
|
+
|
36
|
+
- Properly escape single quote (https://github.com/Beyond-Finance/active_force/pull/29)
|
37
|
+
- Fix `Time` value formatting in `.where` (https://github.com/Beyond-Finance/active_force/pull/28)
|
38
|
+
|
39
|
+
## 0.11.3
|
40
|
+
|
41
|
+
- Fix has_one assignment when receiver does not have id (https://github.com/Beyond-Finance/active_force/pull/23)
|
42
|
+
|
43
|
+
## 0.11.2
|
44
|
+
|
45
|
+
- Fix: prevent association methods from running queries when keys do not exist (https://github.com/Beyond-Finance/active_force/pull/20)
|
46
|
+
|
47
|
+
## 0.11.1
|
48
|
+
|
49
|
+
- Fix `datetime` fields of SObjects to use iso(8601) format when sending to SF (https://github.com/Beyond-Finance/active_force/pull/18)
|
50
|
+
|
51
|
+
## 0.11.0
|
52
|
+
|
53
|
+
- Added support for 'or' and 'not' clauses (https://github.com/Beyond-Finance/active_force/pull/13)
|
54
|
+
- Added support for the SUM aggregate function (https://github.com/Beyond-Finance/active_force/pull/14)
|
55
|
+
- Allow `model` to be passed as a string or a constant (https://github.com/Beyond-Finance/active_force/pull/16)
|
56
|
+
|
57
|
+
## 0.10.0
|
58
|
+
|
59
|
+
- Fix `#where` chaining on `ActiveQuery` (https://github.com/Beyond-Finance/active_force/pull/7)
|
60
|
+
- Add `#find_by!` which raises `ActiveForce::RecordNotFound` if nothing is found. (https://github.com/Beyond-Finance/active_force/pull/8)
|
61
|
+
- Fix `#includes` to find, build, and set the association. (https://github.com/Beyond-Finance/active_force/pull/12)
|
62
|
+
|
63
|
+
## 0.9.1
|
64
|
+
|
65
|
+
- Fix invalid error class (https://github.com/Beyond-Finance/active_force/pull/6)
|
66
|
+
|
67
|
+
## 0.9.0
|
68
|
+
|
69
|
+
- Add support for Rails 7 and update Restforce dependency to newer version. (https://github.com/Beyond-Finance/active_force/pull/3)
|
70
|
+
- Add `has_one` association. (https://github.com/Beyond-Finance/active_force/pull/3)
|
71
|
+
- Model generator enhancements (https://github.com/Beyond-Finance/active_force/pull/3):
|
72
|
+
- automatically add types to fields
|
73
|
+
- sort fields alphabetically
|
74
|
+
- add `table_name` to class
|
75
|
+
- add optional namespace parameter so generated models can be namespaced
|
76
|
+
- Add get/set via `[]` and `[]=` for `SObject` attributes. (https://github.com/Beyond-Finance/active_force/pull/3)
|
4
77
|
|
5
78
|
## 0.7.1
|
6
79
|
|
7
|
-
|
80
|
+
- Allow sfdc_client to be set. ([#92][])
|
8
81
|
|
9
82
|
## 0.7.0
|
10
83
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
84
|
+
- Rails4-style conditional has_many associations ([Dan Olson][])
|
85
|
+
- Add `#includes` query method to eager load has_many association. ([Dan Olson][])
|
86
|
+
- Add `#includes` query method to eager load belongs_to association. ([#65][])
|
87
|
+
- SObject#destroy method.
|
15
88
|
|
16
89
|
## 0.6.1
|
17
90
|
|
18
|
-
|
91
|
+
- Fix missing require of 'restforce'. Now clients don't need to add an initializer.
|
19
92
|
|
20
93
|
## 0.6.0
|
21
94
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
95
|
+
- Add select statement functionality. ([Pablo Oldani][], [#33][])
|
96
|
+
- Add callback functionality ([Pablo Oldani][], [#20][])
|
97
|
+
- Support bind parameters. ([Dan Olson][], [#29][])
|
98
|
+
- Fix when passing nil value in a :where condition. ([Armando Andini][])
|
99
|
+
- Model generator complete ([Armando Andini][], [#19][])
|
27
100
|
|
28
101
|
## 0.5.0
|
29
102
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
103
|
+
- Provide a default id field for all SObject subclassees ([Dan Olson][], [#30][])
|
104
|
+
- Fix Ruby 2.0 compatibility issue ([Dan Olson][], [Pablo Oldani][], [#28][])
|
105
|
+
- Normalize rspec syntax to remove deprecation warnings ([Dan Olson][], [#26][])
|
106
|
+
- Remove namespace when inferring default SObject.table_name ([Dan Olson][], [#24][])
|
107
|
+
- Add create! and save! methods. ([Pablo Oldani][], [#21][])
|
108
|
+
- Refactor update and create methods. ([Pablo Oldani][], [#21][])
|
109
|
+
- Add a generator. ([José Piccioni][], [#19][])
|
110
|
+
- ActiveQuery now provides :each, :map and :inspect. ([Armando Andini][])
|
111
|
+
- Add SObject.create class mehtod. ([Pablo Oldani][], [#10][])
|
112
|
+
- SObject.field default mapping value follows SFDC API naming convention.
|
40
113
|
([Dan Olson][], [#14][] [#15][])
|
41
114
|
|
42
115
|
## 0.4.2
|
43
116
|
|
44
|
-
|
45
|
-
|
46
|
-
|
117
|
+
- Use ActiveQuery instead of Query. ([Armando Andini][])
|
118
|
+
- Add instructions to use validations ([José Piccioni][])
|
119
|
+
- Lots of refactoring.
|
47
120
|
|
48
121
|
## 0.3.2
|
49
122
|
|
50
|
-
|
123
|
+
- Fixed gemspec.
|
51
124
|
|
52
125
|
## 0.3.1
|
53
126
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
127
|
+
- Create different classes for associations. ([#4][])
|
128
|
+
- Big refactor on has_many association. ([Armando Andini][])
|
129
|
+
- Add a lot of specs and refactors. ([Armando Andini][])
|
130
|
+
- Add a Finders module. ([Armando Andini][])
|
131
|
+
- Add fist and last method to SObject.
|
59
132
|
|
60
133
|
## 0.2.0
|
61
134
|
|
62
|
-
|
63
|
-
|
64
|
-
|
135
|
+
- Add belogns_to and has_many associations.
|
136
|
+
- Changed when the SOQL query is sent to the client.
|
137
|
+
- Add join method to query to use associtations.
|
65
138
|
|
66
139
|
## 0.1.0
|
67
140
|
|
68
|
-
|
69
|
-
|
70
|
-
|
141
|
+
- Add query builder object to chain conditions.
|
142
|
+
- Update update and create methods.
|
143
|
+
- Add Campaing standard table name.
|
71
144
|
|
72
145
|
## 0.0.6.alfa
|
73
146
|
|
74
|
-
|
75
|
-
name. It adds "
|
147
|
+
- ActiveForce::SObject#table_name is auto populated using the class
|
148
|
+
name. It adds "\_\_c" to all non standard types.
|
76
149
|
|
77
150
|
<!--- The following link definition list is generated by PimpMyChangelog --->
|
78
151
|
|
@@ -92,7 +165,7 @@
|
|
92
165
|
[#33]: https://github.com/ionia-corporation/active_force/issues/33
|
93
166
|
[#65]: https://github.com/ionia-corporation/active_force/issues/65
|
94
167
|
[#92]: https://github.com/ionia-corporation/active_force/issues/92
|
95
|
-
[
|
96
|
-
[
|
97
|
-
[
|
98
|
-
[
|
168
|
+
[pablo oldani]: https://github.com/olvap
|
169
|
+
[armando andini]: https://github.com/antico5
|
170
|
+
[josé piccioni]: https://github.com/lmhsjackson
|
171
|
+
[dan olson]: https://github.com/DanOlson
|
data/CODEOWNERS
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,29 +1,26 @@
|
|
1
|
-
[![Gem Version](http://img.shields.io/gem/v/active_force.svg)](http://badge.fury.io/rb/active_force)
|
2
|
-
[![Build Status](http://img.shields.io/travis/ionia-corporation/active_force.svg)](https://travis-ci.org/ionia-corporation/active_force)
|
3
|
-
[![Code Climate](http://img.shields.io/codeclimate/github/ionia-corporation/active_force.svg)](https://codeclimate.com/github/ionia-corporation/active_force)
|
4
|
-
[![Dependency Status](http://img.shields.io/gemnasium/ionia-corporation/active_force.svg)](https://gemnasium.com/ionia-corporation/active_force)
|
5
|
-
[![Test Coverage](https://codeclimate.com/github/ionia-corporation/active_force/badges/coverage.svg)](https://codeclimate.com/github/ionia-corporation/active_force)
|
6
|
-
[![Inline docs](http://inch-ci.org/github/ionia-corporation/active_force.png?branch=master)](http://inch-ci.org/github/ionia-corporation/active_force)
|
7
|
-
[![Chat](http://img.shields.io/badge/chat-gitter-brightgreen.svg)](https://gitter.im/ionia-corporation/active_force)
|
8
|
-
|
9
1
|
# ActiveForce
|
10
2
|
|
11
3
|
A ruby gem to interact with [SalesForce][1] as if it were Active Record. It
|
12
4
|
uses [Restforce][2] to interact with the API, so it is fast and stable.
|
13
5
|
|
6
|
+
### Beyond Finance Fork
|
7
|
+
|
8
|
+
This version is forked from the work done by
|
9
|
+
https://github.com/heroku/active_force which was in turn forked from
|
10
|
+
https://github.com/ionia-corporation/active_force.
|
11
|
+
It includes upgrades for Rails 7, as
|
12
|
+
well as additional functionality.
|
13
|
+
|
14
14
|
## Installation
|
15
15
|
|
16
|
-
Add this line to your application's Gemfile
|
16
|
+
Add this line to your application's `Gemfile`:
|
17
17
|
|
18
|
-
gem 'active_force'
|
18
|
+
gem 'active_force', github: "Beyond-Finance/active_force"
|
19
19
|
|
20
20
|
And then execute:
|
21
21
|
|
22
22
|
$ bundle
|
23
23
|
|
24
|
-
Or install it yourself as:
|
25
|
-
|
26
|
-
$ gem install active_force
|
27
24
|
|
28
25
|
## Setup credentials
|
29
26
|
|
@@ -42,7 +39,7 @@ Also, you may specify which client to use as a configuration option, which is us
|
|
42
39
|
when having to reauthenticate utilizing oauth.
|
43
40
|
|
44
41
|
```ruby
|
45
|
-
ActiveForce.sfdc_client = Restforce.new(
|
42
|
+
ActiveForce.sfdc_client = Restforce.new(
|
46
43
|
oauth_token: current_user.oauth_token,
|
47
44
|
refresh_token: current_user.refresh_token,
|
48
45
|
instance_url: current_user.instance_url,
|
@@ -60,14 +57,14 @@ class Medication < ActiveForce::SObject
|
|
60
57
|
|
61
58
|
field :max_dossage # defaults to "Max_Dossage__c"
|
62
59
|
field :updated_from
|
63
|
-
|
60
|
+
|
64
61
|
##
|
65
62
|
# You can cast field value using `as`
|
66
63
|
# field :address_primary_active, from: 's360a__AddressPrimaryActive__c', as: :boolean
|
67
|
-
#
|
68
|
-
# Available options are :boolean, :int, :double, :percent, :date, :datetime, :string, :base64,
|
69
|
-
# :byte, :ID, :reference, :currency, :textarea, :phone, :url, :email, :combobox, :picklist,
|
70
|
-
# :multipicklist, :anyType, :location
|
64
|
+
#
|
65
|
+
# Available options are :boolean, :int, :double, :percent, :date, :datetime, :string, :base64,
|
66
|
+
# :byte, :ID, :reference, :currency, :textarea, :phone, :url, :email, :combobox, :picklist,
|
67
|
+
# :multipicklist, :anyType, :location, :compound
|
71
68
|
|
72
69
|
##
|
73
70
|
# Table name is inferred from class name.
|
@@ -85,11 +82,19 @@ class Medication < ActiveForce::SObject
|
|
85
82
|
# validates :size, inclusion: { in: %w(small medium large),
|
86
83
|
# message: "%{value} is not a valid size" }
|
87
84
|
|
85
|
+
##
|
86
|
+
# Defaults
|
87
|
+
#
|
88
|
+
# Set a default on any field using `default`.
|
89
|
+
field :name, from: 'Name', default: -> { 'default_name' }
|
90
|
+
|
88
91
|
##
|
89
92
|
# Callbacks
|
90
93
|
#
|
91
94
|
before_save :set_as_updated_from_rails
|
92
95
|
|
96
|
+
# Supported callbacks include :build, :create, :update, :save, :destroy
|
97
|
+
|
93
98
|
private
|
94
99
|
|
95
100
|
def set_as_updated_from_rails
|
@@ -101,7 +106,11 @@ end
|
|
101
106
|
|
102
107
|
Altenative you can try the generator. (requires setting up the connection)
|
103
108
|
|
104
|
-
rails generate
|
109
|
+
rails generate active_force:model Medication__c
|
110
|
+
|
111
|
+
The model generator also supports an optional namespace which will add a namespace to the generated model
|
112
|
+
|
113
|
+
rails generate active_force:model Medication__c SomeNamespace
|
105
114
|
|
106
115
|
### Associations
|
107
116
|
|
@@ -117,7 +126,7 @@ class Account < ActiveForce::SObject
|
|
117
126
|
scoped_as: ->{ where("Discontinued__c > ? OR Discontinued__c = ?", Date.today.strftime("%Y-%m-%d"), nil) }
|
118
127
|
|
119
128
|
has_many :today_log_entries,
|
120
|
-
model: DailyLogEntry,
|
129
|
+
model: 'DailyLogEntry',
|
121
130
|
scoped_as: ->{ where(date: Time.now.in_time_zone.strftime("%Y-%m-%d")) }
|
122
131
|
|
123
132
|
has_many :labs,
|
@@ -126,6 +135,15 @@ class Account < ActiveForce::SObject
|
|
126
135
|
end
|
127
136
|
```
|
128
137
|
|
138
|
+
#### Has One
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
class Car < ActiveForce::SObject
|
142
|
+
has_one :engine, model: 'CarEngine'
|
143
|
+
has_one :driver_seat, model: 'Seat', scoped_as: -> { where(can_access_steering_wheel: true).order('Position ASC') }
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
129
147
|
#### Belongs to
|
130
148
|
|
131
149
|
```ruby
|
@@ -149,12 +167,73 @@ Account.where(web_enable: 1, contact_by: ['web', 'email']).limit(2)
|
|
149
167
|
# LIMIT 2
|
150
168
|
```
|
151
169
|
|
170
|
+
You can query using _NOT_ (negated conditions):
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
Account.where.not(web_enable: 1)
|
174
|
+
#=> this will query "SELECT Id, Name...
|
175
|
+
# FROM Account
|
176
|
+
# WHERE NOT WebEnable__c = 1"
|
177
|
+
```
|
178
|
+
|
179
|
+
You can create _OR_ queries:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
Account.where(contact_by: 'web').or(Account.where(contact_by: 'email'))
|
183
|
+
#=> this will query "SELECT Id, Name...
|
184
|
+
# FROM Account
|
185
|
+
# WHERE (contact_by__c = 'web')
|
186
|
+
# OR (contact_by__c = 'email')"
|
187
|
+
```
|
188
|
+
|
152
189
|
It is also possible to eager load associations:
|
153
190
|
|
154
191
|
```ruby
|
155
192
|
Comment.includes(:post)
|
156
193
|
```
|
157
194
|
|
195
|
+
### Aggregates
|
196
|
+
|
197
|
+
Summing the values of a column:
|
198
|
+
```ruby
|
199
|
+
Transaction.where(offer_id: 'ABD832024').sum(:amount)
|
200
|
+
#=> This will query "SELECT SUM(Amount__c)
|
201
|
+
# FROM Transaction__c
|
202
|
+
# WHERE offer_id = 'ABD832024'"
|
203
|
+
```
|
204
|
+
|
205
|
+
#### Decorator
|
206
|
+
|
207
|
+
You can specify a `self.decorate(records)` method on the class, which will be called once with
|
208
|
+
the Restforce API results passed as the only argument. This allows you to decorate the results in one pass
|
209
|
+
through method, which is helpful if you need to bulk modify the returned API results and
|
210
|
+
don't want to incur any N+1 penalties. You must return the new altered array from
|
211
|
+
the decorate method.
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
class Account < ActiveForce::SObject
|
215
|
+
|
216
|
+
##
|
217
|
+
# Decorator
|
218
|
+
#
|
219
|
+
def self.decorate account_records
|
220
|
+
# Perform other API call once for all account_records ids
|
221
|
+
other_things = OtherAPI.find_things_with_ids(account_records.map{ |a| a["Id"] } )
|
222
|
+
account_records.map do |a|
|
223
|
+
# Find other_thing that corresponds to the current account_record
|
224
|
+
other_thing_for_account = other_things.detect{ |o| o["Id"] == a["Id"]}
|
225
|
+
|
226
|
+
# make updates to each record
|
227
|
+
a.merge_in_other_stuff(other_thing_for_account)
|
228
|
+
end # the mapped array will be returned
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
accounts = Account.where(web_enabled: 1).limit(2)
|
233
|
+
# This finds the records from the RestForce API, and then decorate all results
|
234
|
+
with data from another API, and will only query the other API once.
|
235
|
+
```
|
236
|
+
|
158
237
|
### Model generator
|
159
238
|
|
160
239
|
When using rails, you can generate a model with all the fields you have on your SFDC table by running:
|
data/active_force.gemspec
CHANGED
@@ -10,8 +10,13 @@ Gem::Specification.new do |spec|
|
|
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}
|
13
|
-
spec.homepage = "https://github.com/
|
13
|
+
spec.homepage = "https://github.com/Beyond-Finance/active_force#readme"
|
14
14
|
spec.license = "MIT"
|
15
|
+
spec.metadata = {
|
16
|
+
"bug_tracker_uri" => "https://github.com/Beyond-Finance/active_force/issues",
|
17
|
+
"changelog_uri" => "https://github.com/Beyond-Finance/active_force/blob/main/CHANGELOG.md",
|
18
|
+
"source_code_uri" => "https://github.com/Beyond-Finance/active_force",
|
19
|
+
}
|
15
20
|
|
16
21
|
spec.files = `git ls-files`.split($/)
|
17
22
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
@@ -20,10 +25,12 @@ Gem::Specification.new do |spec|
|
|
20
25
|
|
21
26
|
spec.required_ruby_version = '>= 1.9.3'
|
22
27
|
|
23
|
-
spec.add_dependency '
|
24
|
-
spec.add_dependency '
|
25
|
-
spec.
|
28
|
+
spec.add_dependency 'activemodel', '~> 7.0'
|
29
|
+
spec.add_dependency 'activesupport', '~> 7.0'
|
30
|
+
spec.add_dependency 'restforce', '>= 5'
|
26
31
|
spec.add_development_dependency 'rake', '>= 0'
|
27
32
|
spec.add_development_dependency 'rspec', '>= 0'
|
33
|
+
spec.add_development_dependency 'rspec_junit_formatter'
|
28
34
|
spec.add_development_dependency 'pry', '>= 0'
|
35
|
+
spec.add_development_dependency 'simplecov', '>= 0'
|
29
36
|
end
|