active_force 0.7.0 → 0.15.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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +107 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +24 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.mailmap +3 -0
  6. data/CHANGELOG.md +122 -41
  7. data/CODEOWNERS +2 -0
  8. data/Gemfile +0 -1
  9. data/README.md +116 -16
  10. data/active_force.gemspec +11 -4
  11. data/lib/active_force/active_query.rb +107 -6
  12. data/lib/active_force/association/association.rb +48 -4
  13. data/lib/active_force/association/belongs_to_association.rb +25 -11
  14. data/lib/active_force/association/eager_load_projection_builder.rb +9 -3
  15. data/lib/active_force/association/has_many_association.rb +19 -19
  16. data/lib/active_force/association/has_one_association.rb +30 -0
  17. data/lib/active_force/association/relation_model_builder.rb +1 -1
  18. data/lib/active_force/association.rb +6 -4
  19. data/lib/active_force/{attribute.rb → field.rb} +3 -3
  20. data/lib/active_force/mapping.rb +6 -32
  21. data/lib/active_force/query.rb +21 -2
  22. data/lib/active_force/sobject.rb +75 -29
  23. data/lib/active_force/version.rb +3 -1
  24. data/lib/active_force.rb +9 -0
  25. data/lib/active_model/type/salesforce/multipicklist.rb +29 -0
  26. data/lib/active_model/type/salesforce/percent.rb +22 -0
  27. data/lib/generators/active_force/model/model_generator.rb +32 -21
  28. data/lib/generators/active_force/model/templates/model.rb.erb +3 -1
  29. data/spec/active_force/active_query_spec.rb +200 -8
  30. data/spec/active_force/association/relation_model_builder_spec.rb +22 -0
  31. data/spec/active_force/association_spec.rb +253 -10
  32. data/spec/active_force/callbacks_spec.rb +1 -1
  33. data/spec/active_force/field_spec.rb +34 -0
  34. data/spec/active_force/query_spec.rb +26 -0
  35. data/spec/active_force/sobject/includes_spec.rb +11 -11
  36. data/spec/active_force/sobject_spec.rb +223 -16
  37. data/spec/fixtures/sobject/single_sobject_hash.yml +1 -1
  38. data/spec/spec_helper.rb +5 -2
  39. data/spec/support/bangwhiz.rb +7 -0
  40. data/spec/support/restforce_factories.rb +1 -1
  41. data/spec/support/sobjects.rb +17 -1
  42. data/spec/support/whizbang.rb +2 -2
  43. metadata +64 -25
  44. data/lib/active_attr/dirty.rb +0 -24
  45. data/spec/active_force/attribute_spec.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f65b3ee4d09a2cc85b6ff35e563104b90e35ef2e
4
- data.tar.gz: 865295aff9ee4dfc2962fa13225d41041f3100d1
2
+ SHA256:
3
+ metadata.gz: 661e75020c19d46986c8556c2e39799831468741b96909bab00f40d3ffb1294c
4
+ data.tar.gz: c2549061250e05f2f145c3129c4f83c1d973b09097c77e03592b68b892f54e02
5
5
  SHA512:
6
- metadata.gz: 54eac72eb1033454434c97b997810587004df5655134574a445f8826318c69eda74783f2a902bd75cffe4addd88a41b49b93451029284d2002ca4c2928c3c988
7
- data.tar.gz: 509928a1158a20cb8122efa37d98e893bf762ad1b9cf7329f35cf68ffed269fcd738a4613357bf4ec3830e86cffa6002b9d153baf6689356f555f5836f9b0248
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
@@ -0,0 +1,3 @@
1
+ Armando Andini <armando.andini@hotmail.com>
2
+ Jose Piccioni <josepiccioni@gmail.com> <jackson@jackPc.(none)>
3
+ Pablo Oldani <oldani.pablo@gmail.com>
data/CHANGELOG.md CHANGED
@@ -1,71 +1,151 @@
1
1
  # Changelog
2
2
 
3
3
  ## Not released
4
- * Rails4-style conditional has_many associations ([Dan Olson][])
5
- * Add `#includes` query method to eager load has_many association. ([Dan Olson][])
6
- * Add `#includes` query method to eager load belongs_to association. ([#65][])
7
- * SObject#destroy method.
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)
77
+
78
+ ## 0.7.1
79
+
80
+ - Allow sfdc_client to be set. ([#92][])
81
+
82
+ ## 0.7.0
83
+
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.
8
88
 
9
89
  ## 0.6.1
10
90
 
11
- * Fix missing require of 'restforce'. Now clients don't need to add an initializer.
91
+ - Fix missing require of 'restforce'. Now clients don't need to add an initializer.
12
92
 
13
93
  ## 0.6.0
14
94
 
15
- * Add select statement functionality. ([Pablo Oldani][], [#33][])
16
- * Add callback functionality ([Pablo Oldani][], [#20][])
17
- * Support bind parameters. ([Dan Olson][], [#29][])
18
- * Fix when passing nil value in a :where condition. ([Armando Andini][])
19
- * Model generator complete ([Armando Andini][], [#19][])
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][])
20
100
 
21
101
  ## 0.5.0
22
102
 
23
- * Provide a default id field for all SObject subclassees ([Dan Olson][], [#30][])
24
- * Fix Ruby 2.0 compatibility issue ([Dan Olson][], [Pablo Oldani][], [#28][])
25
- * Normalize rspec syntax to remove deprecation warnings ([Dan Olson][], [#26][])
26
- * Remove namespace when inferring default SObject.table_name ([Dan Olson][], [#24][])
27
- * Add create! and save! methods. ([Pablo Oldani][], [#21][])
28
- * Refactor update and create methods. ([Pablo Oldani][], [#21][])
29
- * Add a generator. ([José Piccioni][], [#19][])
30
- * ActiveQuery now provides :each, :map and :inspect. ([Armando Andini][])
31
- * Add SObject.create class mehtod. ([Pablo Oldani][], [#10][])
32
- * SObject.field default mapping value follows SFDC API naming convention.
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.
33
113
  ([Dan Olson][], [#14][] [#15][])
34
114
 
35
115
  ## 0.4.2
36
116
 
37
- * Use ActiveQuery instead of Query. ([Armando Andini][])
38
- * Add instructions to use validations ([José Piccioni][])
39
- * Lots of refactoring.
117
+ - Use ActiveQuery instead of Query. ([Armando Andini][])
118
+ - Add instructions to use validations ([José Piccioni][])
119
+ - Lots of refactoring.
40
120
 
41
121
  ## 0.3.2
42
122
 
43
- * Fixed gemspec.
123
+ - Fixed gemspec.
44
124
 
45
125
  ## 0.3.1
46
126
 
47
- * Create different classes for associations. ([#4][])
48
- * Big refactor on has_many association. ([Armando Andini][])
49
- * Add a lot of specs and refactors. ([Armando Andini][])
50
- * Add a Finders module. ([Armando Andini][])
51
- * Add fist and last method to SObject.
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.
52
132
 
53
133
  ## 0.2.0
54
134
 
55
- * Add belogns_to and has_many associations.
56
- * Changed when the SOQL query is sent to the client.
57
- * Add join method to query to use associtations.
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.
58
138
 
59
139
  ## 0.1.0
60
140
 
61
- * Add query builder object to chain conditions.
62
- * Update update and create methods.
63
- * Add Campaing standard table name.
141
+ - Add query builder object to chain conditions.
142
+ - Update update and create methods.
143
+ - Add Campaing standard table name.
64
144
 
65
145
  ## 0.0.6.alfa
66
146
 
67
- * ActiveForce::SObject#table_name is auto populated using the class
68
- name. It adds "__c" to all non standard types.
147
+ - ActiveForce::SObject#table_name is auto populated using the class
148
+ name. It adds "\_\_c" to all non standard types.
69
149
 
70
150
  <!--- The following link definition list is generated by PimpMyChangelog --->
71
151
 
@@ -84,7 +164,8 @@
84
164
  [#30]: https://github.com/ionia-corporation/active_force/issues/30
85
165
  [#33]: https://github.com/ionia-corporation/active_force/issues/33
86
166
  [#65]: https://github.com/ionia-corporation/active_force/issues/65
87
- [Pablo Oldani]: https://github.com/olvap
88
- [Armando Andini]: https://github.com/antico5
89
- [José Piccioni]: https://github.com/lmhsjackson
90
- [Dan Olson]: https://github.com/DanOlson
167
+ [#92]: https://github.com/ionia-corporation/active_force/issues/92
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
@@ -0,0 +1,2 @@
1
+ # Comment line immediately above ownership line is reserved for related gus information. Please be careful while editing.
2
+ #ECCN:Open Source
data/Gemfile CHANGED
@@ -1,5 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in active_force.gemspec
4
- gem "codeclimate-test-reporter", group: :test, require: nil
5
4
  gemspec
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
 
@@ -38,6 +35,19 @@ environment variables to set up credentials.
38
35
 
39
36
  You might be interested in [dotenv-rails][3] to set up those in development.
40
37
 
38
+ Also, you may specify which client to use as a configuration option, which is useful
39
+ when having to reauthenticate utilizing oauth.
40
+
41
+ ```ruby
42
+ ActiveForce.sfdc_client = Restforce.new(
43
+ oauth_token: current_user.oauth_token,
44
+ refresh_token: current_user.refresh_token,
45
+ instance_url: current_user.instance_url,
46
+ client_id: SALESFORCE_CLIENT_ID,
47
+ client_secret: SALESFORCE_CLIENT_SECRET
48
+ )
49
+ ```
50
+
41
51
  ## Usage
42
52
 
43
53
  ```ruby
@@ -48,6 +58,14 @@ class Medication < ActiveForce::SObject
48
58
  field :max_dossage # defaults to "Max_Dossage__c"
49
59
  field :updated_from
50
60
 
61
+ ##
62
+ # You can cast field value using `as`
63
+ # field :address_primary_active, from: 's360a__AddressPrimaryActive__c', as: :boolean
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
68
+
51
69
  ##
52
70
  # Table name is inferred from class name.
53
71
  #
@@ -64,11 +82,19 @@ class Medication < ActiveForce::SObject
64
82
  # validates :size, inclusion: { in: %w(small medium large),
65
83
  # message: "%{value} is not a valid size" }
66
84
 
85
+ ##
86
+ # Defaults
87
+ #
88
+ # Set a default on any field using `default`.
89
+ field :name, from: 'Name', default: -> { 'default_name' }
90
+
67
91
  ##
68
92
  # Callbacks
69
93
  #
70
94
  before_save :set_as_updated_from_rails
71
95
 
96
+ # Supported callbacks include :build, :create, :update, :save, :destroy
97
+
72
98
  private
73
99
 
74
100
  def set_as_updated_from_rails
@@ -80,7 +106,11 @@ end
80
106
 
81
107
  Altenative you can try the generator. (requires setting up the connection)
82
108
 
83
- rails generate active_force_model Medication__c
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
84
114
 
85
115
  ### Associations
86
116
 
@@ -96,8 +126,8 @@ class Account < ActiveForce::SObject
96
126
  scoped_as: ->{ where("Discontinued__c > ? OR Discontinued__c = ?", Date.today.strftime("%Y-%m-%d"), nil) }
97
127
 
98
128
  has_many :today_log_entries,
99
- model: DailyLogEntry,
100
- scoped_as: ->{ where(date: Time.now.in_time_zone.strftime("%Y-%m-%d") }
129
+ model: 'DailyLogEntry',
130
+ scoped_as: ->{ where(date: Time.now.in_time_zone.strftime("%Y-%m-%d")) }
101
131
 
102
132
  has_many :labs,
103
133
  scoped_as: ->{ where("Category__c = 'EMR' AND Date__c <> NULL").order('Date__c DESC') }
@@ -105,6 +135,15 @@ class Account < ActiveForce::SObject
105
135
  end
106
136
  ```
107
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
+
108
147
  #### Belongs to
109
148
 
110
149
  ```ruby
@@ -128,12 +167,73 @@ Account.where(web_enable: 1, contact_by: ['web', 'email']).limit(2)
128
167
  # LIMIT 2
129
168
  ```
130
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
+
131
189
  It is also possible to eager load associations:
132
190
 
133
191
  ```ruby
134
192
  Comment.includes(:post)
135
193
  ```
136
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
+
137
237
  ### Model generator
138
238
 
139
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/ionia-corporation/active_force"
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 'active_attr', '~> 0.8'
24
- spec.add_dependency 'restforce', '~> 1.4'
25
- spec.add_development_dependency 'bundler', '~> 1.3'
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