restforce-db 2.0.1 → 2.1.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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/lib/restforce/db/associations/base.rb +7 -7
  4. data/lib/restforce/db/associations/belongs_to.rb +6 -10
  5. data/lib/restforce/db/associations/foreign_key.rb +1 -2
  6. data/lib/restforce/db/associations/has_many.rb +2 -1
  7. data/lib/restforce/db/associations/has_one.rb +2 -1
  8. data/lib/restforce/db/cleaner.rb +25 -3
  9. data/lib/restforce/db/configuration.rb +7 -0
  10. data/lib/restforce/db/record_types/active_record.rb +5 -1
  11. data/lib/restforce/db/version.rb +1 -1
  12. data/lib/restforce/db.rb +1 -0
  13. data/test/cassettes/Restforce_DB/accessing_Salesforce/uses_the_configured_credentials.yml +1 -1
  14. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_build/returns_an_associated_record_populated_with_the_Salesforce_attributes.yml +17 -17
  15. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_build/when_no_salesforce_record_is_found_for_the_association/proceeds_without_constructing_any_records.yml +11 -11
  16. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_build/when_the_associated_record_has_already_been_persisted/assigns_the_existing_record.yml +17 -17
  17. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_build/when_the_associated_record_has_been_cached/uses_the_cached_record.yml +17 -17
  18. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_build/when_the_association_is_non-building/proceeds_without_constructing_any_records.yml +14 -14
  19. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_build/with_an_unrelated_association_mapping/proceeds_without_raising_an_error.yml +17 -17
  20. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_lookups/returns_a_hash_of_the_associated_records_lookup_IDs.yml +11 -11
  21. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_lookups/when_there_is_currently_no_associated_record/and_the_underlying_association_is_one-to-many/still_returns_a_nil_lookup_value_in_the_hash.yml +119 -0
  22. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_lookups/when_there_is_currently_no_associated_record/returns_a_nil_lookup_value_in_the_hash.yml +6 -6
  23. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_synced_for_/when_a_matching_associated_record_has_been_synchronized/returns_true.yml +17 -17
  24. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_synced_for_/when_no_matching_associated_record_has_been_synchronized/returns_false.yml +17 -17
  25. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_build/builds_a_number_of_associated_records_from_the_data_in_Salesforce.yml +29 -29
  26. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_build/when_no_salesforce_record_is_found_for_the_association/proceeds_without_constructing_any_records.yml +11 -11
  27. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_build/when_the_associated_records_have_alrady_been_persisted/constructs_the_association_from_the_existing_records.yml +29 -29
  28. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_build/when_the_associated_records_have_been_cached/uses_the_cached_records.yml +29 -29
  29. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_build/when_the_association_is_non-building/proceeds_without_constructing_any_records.yml +9 -9
  30. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_synced_for_/when_a_matching_associated_record_has_been_synchronized/returns_true.yml +29 -29
  31. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_synced_for_/when_no_matching_associated_record_has_been_synchronized/returns_false.yml +11 -11
  32. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_build/and_a_nested_association_on_the_associated_mapping/recursively_builds_all_associations.yml +25 -25
  33. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_build/returns_an_associated_record_populated_with_the_Salesforce_attributes.yml +17 -17
  34. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_build/when_no_salesforce_record_is_found_for_the_association/proceeds_without_constructing_any_records.yml +11 -11
  35. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_build/when_the_associated_record_has_already_been_persisted/assigns_the_existing_record.yml +17 -17
  36. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_build/when_the_associated_record_has_been_cached/uses_the_cached_record.yml +17 -17
  37. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_build/when_the_association_is_non-building/proceeds_without_constructing_any_records.yml +14 -14
  38. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_synced_for_/when_a_matching_associated_record_has_been_synchronized/returns_true.yml +17 -17
  39. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_synced_for_/when_no_matching_associated_record_has_been_synchronized/returns_false.yml +17 -17
  40. data/test/cassettes/Restforce_DB_Associator/_run/given_a_BelongsTo_association/given_another_record_for_association/when_the_Salesforce_association_is_out_of_date/updates_the_association_ID_in_Salesforce.yml +30 -30
  41. data/test/cassettes/Restforce_DB_Associator/_run/given_a_BelongsTo_association/given_another_record_for_association/when_the_database_association_is_out_of_date/updates_the_associated_record_in_the_database.yml +33 -33
  42. data/test/cassettes/Restforce_DB_Cleaner/_run/given_a_synchronized_Salesforce_record/when_the_mapping_has_no_conditions/does_not_drop_the_synchronized_database_record.yml +6 -6
  43. data/test/cassettes/Restforce_DB_Cleaner/_run/given_a_synchronized_Salesforce_record/when_the_record_does_not_meet_the_mapping_conditions/but_meets_conditions_for_a_parallel_mapping/does_not_drop_the_synchronized_database_record.yml +238 -0
  44. data/test/cassettes/Restforce_DB_Cleaner/_run/given_a_synchronized_Salesforce_record/when_the_record_does_not_meet_the_mapping_conditions/{for_a_non-Passive_strategy/drops_the_synchronized_database_record.yml → drops_the_synchronized_database_record.yml} +11 -11
  45. data/test/cassettes/Restforce_DB_Cleaner/_run/given_a_synchronized_Salesforce_record/when_the_record_meets_the_mapping_conditions/does_not_drop_the_synchronized_database_record.yml +12 -12
  46. data/test/cassettes/Restforce_DB_Collector/_run/given_a_Salesforce_record_with_an_associated_database_record/returns_the_attributes_from_both_records.yml +12 -12
  47. data/test/cassettes/Restforce_DB_Collector/_run/given_an_existing_Salesforce_record/returns_the_attributes_from_the_Salesforce_record.yml +12 -12
  48. data/test/cassettes/Restforce_DB_Collector/_run/given_an_existing_database_record/returns_the_attributes_from_the_database_record.yml +3 -3
  49. data/test/cassettes/Restforce_DB_Initializer/_run/given_an_existing_Salesforce_record/for_a_Passive_strategy/does_not_create_a_database_record.yml +6 -6
  50. data/test/cassettes/Restforce_DB_Initializer/_run/given_an_existing_Salesforce_record/for_an_Always_strategy/creates_a_matching_database_record.yml +10 -10
  51. data/test/cassettes/Restforce_DB_Initializer/_run/given_an_existing_database_record/for_an_Always_strategy/populates_Salesforce_with_the_new_record.yml +17 -17
  52. data/test/cassettes/Restforce_DB_Instances_Salesforce/_synced_/when_a_matching_database_record_exists/returns_true.yml +9 -9
  53. data/test/cassettes/Restforce_DB_Instances_Salesforce/_synced_/when_no_matching_database_record_exists/returns_false.yml +9 -9
  54. data/test/cassettes/Restforce_DB_Instances_Salesforce/_update_/updates_the_local_record_with_the_passed_attributes.yml +14 -14
  55. data/test/cassettes/Restforce_DB_Instances_Salesforce/_update_/updates_the_record_in_Salesforce_with_the_passed_attributes.yml +17 -17
  56. data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_all/returns_a_list_of_the_existing_records_in_Salesforce.yml +9 -9
  57. data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_create_/creates_a_record_in_Salesforce_from_the_passed_database_record_s_attributes.yml +12 -12
  58. data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_create_/updates_the_database_record_with_the_Salesforce_record_s_ID.yml +12 -12
  59. data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_find/finds_existing_records_in_Salesforce.yml +9 -9
  60. data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_find/given_a_set_of_mapping_conditions/when_a_record_does_not_meet_the_conditions/does_not_find_the_record.yml +8 -8
  61. data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_find/given_a_set_of_mapping_conditions/when_a_record_meets_the_conditions/finds_the_record.yml +9 -9
  62. data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_find/returns_nil_when_no_matching_record_exists.yml +3 -3
  63. data/test/cassettes/Restforce_DB_Strategies_Always/_build_/given_a_Salesforce_record/wants_to_build_a_new_matching_record.yml +9 -9
  64. data/test/cassettes/Restforce_DB_Strategies_Always/_build_/given_a_Salesforce_record/with_a_corresponding_database_record/does_not_want_to_build_a_new_record.yml +9 -9
  65. data/test/cassettes/Restforce_DB_Strategies_Associated/_build_/given_an_inverse_mapping/with_a_synchronized_association_record/wants_to_build_a_new_record.yml +17 -17
  66. data/test/cassettes/Restforce_DB_Strategies_Associated/_build_/given_an_inverse_mapping/with_an_existing_database_record/does_not_want_to_build_a_new_record.yml +14 -14
  67. data/test/cassettes/Restforce_DB_Strategies_Associated/_build_/given_an_inverse_mapping/with_no_synchronized_association_record/does_not_want_to_build_a_new_record.yml +17 -17
  68. data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/updates_the_database_record.yml +14 -14
  69. data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/updates_the_salesforce_record.yml +17 -17
  70. data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_no_associated_database_record/does_nothing_for_this_specific_mapping.yml +12 -12
  71. data/test/lib/restforce/db/associations/belongs_to_test.rb +17 -0
  72. data/test/lib/restforce/db/cleaner_test.rb +20 -4
  73. data/test/support/active_record.rb +3 -0
  74. data/test/support/vcr.rb +8 -0
  75. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd30e064e5e85ed7a3324e54e08797f34df84c84
4
- data.tar.gz: 43bf5c31a7517094be1fbb875c701d9b580a4121
3
+ metadata.gz: 01480e73730d073d3a32cd98e857fc1e52929b61
4
+ data.tar.gz: 84030dcc6a219ded9d5b2aae3bebc2b206dcb19f
5
5
  SHA512:
6
- metadata.gz: 9c8c3b7f0ce2cd131c643f2d33f7c15c719b820522e67696bb6d6a4eeb9ef80a77d4a841d8a7d0bf7a8a66fd9caf252357e29cd245f4257823a9d85c55cb9e63
7
- data.tar.gz: e75e5b35ed86a07426eea1926ae642d7176167a7de858934a3e251399efe0f85af30fca97e1ea12f93ff9fbcddf7bf925bd08221bb1158e9520987da5ea16d46
6
+ metadata.gz: a450050d89860044d184914a5b2467b6d62c43eaaf194fc75779047650e570310429141a9a27e6ed0614cd73df66d961d5ca218b7a56cbfb933d7b291d59f38d
7
+ data.tar.gz: 173e619cb910940d302e11508425b4149f8f2f88ac8739917c22915c491a6aadf601f8ce8d5b41c0f8fefe03d62092988dbebc129cf698ff0d9adf21cc21e131
data/README.md CHANGED
@@ -229,6 +229,9 @@ For additional information and a full set of options, you can run:
229
229
  - **API Usage.**
230
230
  This gem performs most of its functionality via the Salesforce API (by way of the [`restforce`](https://github.com/ejholmes/restforce) gem). If you're at risk of hitting your Salesforce API limits, this may not be the right approach for you.
231
231
 
232
+ - **API Version.**
233
+ Restforce::DB defaults to version 29.0 of the Salesforce API. If you need a more (or less, for whatever reason) recent version of the API for your use case, you can specify an `api_version` key in your restforce-db.yml configuration. Version 29.0 or above is required for full gem functionality.
234
+
232
235
  - **Update Prioritization.**
233
236
  When synchronization occurs, the most recently updated record, Salesforce or database, gets to make the final call about the values of _all_ of the fields it observes. This means that race conditions can and probably will happen if both systems are updated within the same polling interval.
234
237
 
@@ -46,11 +46,11 @@ module Restforce
46
46
  #
47
47
  # Returns a Boolean.
48
48
  def synced_for?(instance)
49
- base_class = instance.mapping.database_model
50
- reflection = base_class.reflect_on_association(name)
51
49
  association_id = associated_salesforce_id(instance)
52
-
53
50
  return false unless association_id
51
+
52
+ base_class = instance.mapping.database_model
53
+ reflection = base_class.reflect_on_association(name)
54
54
  reflection.klass.exists?(
55
55
  mapping_for(reflection).lookup_column => association_id,
56
56
  )
@@ -69,12 +69,12 @@ module Restforce
69
69
  # Internal: Get the appropriate Salesforce Lookup ID field for the
70
70
  # passed mapping.
71
71
  #
72
- # mapping - A Restforce::DB::Mapping.
73
- # database_record - An instance of an ActiveRecord::Base subclass.
72
+ # mapping - A Restforce::DB::Mapping.
73
+ # reflection - An ActiveRecord::AssociationReflection.
74
74
  #
75
75
  # Returns a String or nil.
76
- def lookup_field(mapping, database_record)
77
- inverse = inverse_association_name(target_reflection(database_record))
76
+ def lookup_field(mapping, reflection)
77
+ inverse = inverse_association_name(reflection)
78
78
  association = mapping.associations.detect { |a| a.name == inverse }
79
79
  return unless association
80
80
 
@@ -57,15 +57,11 @@ module Restforce
57
57
  ids = {}
58
58
 
59
59
  for_mappings(database_record) do |mapping, lookup|
60
- associated = database_record.association(name).reader
61
-
62
- ids[lookup] =
63
- if associated
64
- # It's possible to define a belongs_to association in a Mapping
65
- # for what is actually a one-to-many association on the
66
- # ActiveRecord object.
67
- Array(associated).first.send(mapping.lookup_column)
68
- end
60
+ # It's possible to define a belongs_to association in a Mapping
61
+ # for what is actually a one-to-many association on the
62
+ # ActiveRecord object, so we always treat the result as an Array.
63
+ associated = Array(database_record.association(name).reader)
64
+ ids[lookup] = associated.empty? ? nil : associated.first.send(mapping.lookup_column)
69
65
  end
70
66
 
71
67
  ids
@@ -82,7 +78,7 @@ module Restforce
82
78
  # Returns nothing.
83
79
  def for_mappings(database_record)
84
80
  Registry[target_class(database_record)].each do |mapping|
85
- lookup = lookup_field(mapping, database_record)
81
+ lookup = lookup_field(mapping, target_reflection(database_record))
86
82
  next unless lookup
87
83
  yield mapping, lookup
88
84
  end
@@ -61,11 +61,10 @@ module Restforce
61
61
  #
62
62
  # Returns a String.
63
63
  def associated_salesforce_id(instance)
64
- query = "#{lookup} = '#{instance.id}'"
65
-
66
64
  reflection = instance.mapping.database_model.reflect_on_association(name)
67
65
  inverse_mapping = mapping_for(reflection)
68
66
 
67
+ query = "#{lookup_field(inverse_mapping, reflection)} = '#{instance.id}'"
69
68
  salesforce_instance = inverse_mapping.salesforce_record_type.first(query)
70
69
  salesforce_instance.id if salesforce_instance
71
70
  end
@@ -23,7 +23,8 @@ module Restforce
23
23
  @cache = cache
24
24
 
25
25
  target = target_mapping(database_record)
26
- lookup_id = "#{lookup_field(target, database_record)} = '#{salesforce_record.Id}'"
26
+ reflection = target_reflection(database_record)
27
+ lookup_id = "#{lookup_field(target, reflection)} = '#{salesforce_record.Id}'"
27
28
 
28
29
  records = []
29
30
  target.salesforce_record_type.all(conditions: lookup_id).each do |instance|
@@ -23,7 +23,8 @@ module Restforce
23
23
  @cache = cache
24
24
 
25
25
  target = target_mapping(database_record)
26
- query = "#{lookup_field(target, database_record)} = '#{salesforce_record.Id}'"
26
+ reflection = target_reflection(database_record)
27
+ query = "#{lookup_field(target, reflection)} = '#{salesforce_record.Id}'"
27
28
 
28
29
  instance = target.salesforce_record_type.first(query)
29
30
  instance ? construct_for(database_record, instance) : []
@@ -40,19 +40,41 @@ module Restforce
40
40
  #
41
41
  # Returns an Array of IDs.
42
42
  def all_salesforce_ids
43
- @mapping.unscoped { valid_salesforce_ids }
43
+ @mapping.unscoped { salesforce_ids(@mapping) }
44
+ end
45
+
46
+ # Internal: Get the IDs of the recently-modified Salesforce records for
47
+ # mappings between the same object types.
48
+ #
49
+ # Returns an Array of IDs.
50
+ def valid_salesforce_ids
51
+ parallel_mappings.flat_map { |mapping| salesforce_ids(mapping) }
44
52
  end
45
53
 
46
54
  # Internal: Get the IDs of the recently-modified Salesforce records which
47
55
  # meet the conditions for this mapping.
48
56
  #
57
+ # mapping - A Restforce::DB::Mapping.
58
+ #
49
59
  # Returns an Array of IDs.
50
- def valid_salesforce_ids
51
- @runner.run(@mapping) do |run|
60
+ def salesforce_ids(mapping)
61
+ @runner.run(mapping) do |run|
52
62
  run.salesforce_instances.map(&:id)
53
63
  end
54
64
  end
55
65
 
66
+ # Internal: Get a list of mappings between identical Salesforce and
67
+ # database record types. This allows us to protect against inadvertently
68
+ # removing records which belong to a parallel mapping on the same
69
+ # ActiveRecord class.
70
+ #
71
+ # Rturns an Array of Mappings.
72
+ def parallel_mappings
73
+ Registry[@mapping.database_model].select do |mapping|
74
+ mapping.salesforce_model == @mapping.salesforce_model
75
+ end
76
+ end
77
+
56
78
  end
57
79
 
58
80
  end
@@ -8,6 +8,8 @@ module Restforce
8
8
  # and read methods to allow users to configure Restforce::DB.
9
9
  class Configuration
10
10
 
11
+ DEFAULT_API_VERSION = "29.0".freeze
12
+
11
13
  attr_accessor(*%i(
12
14
  username
13
15
  password
@@ -15,6 +17,7 @@ module Restforce
15
17
  client_id
16
18
  client_secret
17
19
  host
20
+ api_version
18
21
  ))
19
22
 
20
23
  # Public: Parse a supplied YAML file for a set of credentials, and use
@@ -41,6 +44,10 @@ module Restforce
41
44
  self.client_id = parsed(configurations, "client_id")
42
45
  self.client_secret = parsed(configurations, "client_secret")
43
46
  self.host = parsed(configurations, "host")
47
+
48
+ # We want to default to 29.0 or later, so we can support the API
49
+ # endpoint for recently deleted records.
50
+ self.api_version = configurations["api_version"] || DEFAULT_API_VERSION
44
51
  end
45
52
 
46
53
  private
@@ -19,7 +19,11 @@ module Restforce
19
19
  def create!(from_record)
20
20
  record = @record_type.find_or_initialize_by(@mapping.lookup_column => from_record.id)
21
21
  record.assign_attributes(@mapping.convert(@record_type, from_record.attributes))
22
- associations = @mapping.associations.flat_map { |a| a.build(record, from_record.record) }
22
+
23
+ cache = AssociationCache.new(record)
24
+ associations = @mapping.associations.flat_map do |association|
25
+ association.build(record, from_record.record, cache)
26
+ end
23
27
 
24
28
  record.transaction do
25
29
  record.save!
@@ -3,7 +3,7 @@ module Restforce
3
3
  # :nodoc:
4
4
  module DB
5
5
 
6
- VERSION = "2.0.1"
6
+ VERSION = "2.1.0"
7
7
 
8
8
  end
9
9
 
data/lib/restforce/db.rb CHANGED
@@ -78,6 +78,7 @@ module Restforce
78
78
  client_id: configuration.client_id,
79
79
  client_secret: configuration.client_secret,
80
80
  host: configuration.host,
81
+ api_version: configuration.api_version,
81
82
  )
82
83
  end
83
84
 
@@ -38,6 +38,6 @@ http_interactions:
38
38
  body:
39
39
  encoding: ASCII-8BIT
40
40
  string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1427365218093","token_type":"Bearer","instance_url":"https://<host>","signature":"zr8yut/9lhLfOwHlsCXPJ635XLUaIg62ecMRMW7mAV4=","access_token":"00D1a000000H3O9!AQ4AQFqDs34WtnS6RDwxyGdLSPYE_cFTuNjjnDvX2HbNhGMu917m6JyqchGFbdiOruyd5Z.w7uN.ogsJF4_8TMMzdt2fw7OZ"}'
41
- http_version:
41
+ http_version:
42
42
  recorded_at: Thu, 26 Mar 2015 10:20:18 GMT
43
43
  recorded_with: VCR 2.9.3
@@ -38,11 +38,11 @@ http_interactions:
38
38
  body:
39
39
  encoding: ASCII-8BIT
40
40
  string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1428631827849","token_type":"Bearer","instance_url":"https://<host>","signature":"BXGR8ydlpCf8EvBey3owrmD+t8H2Xwv4wg5rPNZH7o0=","access_token":"00D1a000000H3O9!AQ4AQNe4R8V.LO2wVndhS1VuuxNtdXS1JCvyNPnzJvH6QSXO9uYDDviw_E1.9iDm2CAsI8PipNylFdpNxUnQrofmMfc7RNsW"}'
41
- http_version:
41
+ http_version:
42
42
  recorded_at: Fri, 10 Apr 2015 02:10:29 GMT
43
43
  - request:
44
44
  method: post
45
- uri: https://<host>/services/data/v26.0/sobjects/Contact
45
+ uri: https://<host>/services/data/<api_version>/sobjects/Contact
46
46
  body:
47
47
  encoding: UTF-8
48
48
  string: '{"Email":"somebody@example.com","LastName":"Somebody"}'
@@ -72,7 +72,7 @@ http_interactions:
72
72
  Sforce-Limit-Info:
73
73
  - api-usage=11/15000
74
74
  Location:
75
- - "/services/data/v26.0/sobjects/Contact/0031a000001y45eAAA"
75
+ - "/services/data/<api_version>/sobjects/Contact/0031a000001y45eAAA"
76
76
  Content-Type:
77
77
  - application/json;charset=UTF-8
78
78
  Transfer-Encoding:
@@ -80,11 +80,11 @@ http_interactions:
80
80
  body:
81
81
  encoding: ASCII-8BIT
82
82
  string: '{"id":"0031a000001y45eAAA","success":true,"errors":[]}'
83
- http_version:
83
+ http_version:
84
84
  recorded_at: Fri, 10 Apr 2015 02:10:30 GMT
85
85
  - request:
86
86
  method: post
87
- uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c
87
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c
88
88
  body:
89
89
  encoding: UTF-8
90
90
  string: '{"Friend__c":"0031a000001y45eAAA"}'
@@ -114,7 +114,7 @@ http_interactions:
114
114
  Sforce-Limit-Info:
115
115
  - api-usage=11/15000
116
116
  Location:
117
- - "/services/data/v26.0/sobjects/CustomObject__c/a001a000001LS2EAAW"
117
+ - "/services/data/<api_version>/sobjects/CustomObject__c/a001a000001LS2EAAW"
118
118
  Content-Type:
119
119
  - application/json;charset=UTF-8
120
120
  Transfer-Encoding:
@@ -122,11 +122,11 @@ http_interactions:
122
122
  body:
123
123
  encoding: ASCII-8BIT
124
124
  string: '{"id":"a001a000001LS2EAAW","success":true,"errors":[]}'
125
- http_version:
125
+ http_version:
126
126
  recorded_at: Fri, 10 Apr 2015 02:10:31 GMT
127
127
  - request:
128
128
  method: get
129
- uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Name,%20Example_Field__c,%20Friend__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001LS2EAAW%27
129
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20Name,%20Example_Field__c,%20Friend__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001LS2EAAW%27
130
130
  body:
131
131
  encoding: US-ASCII
132
132
  string: ''
@@ -159,12 +159,12 @@ http_interactions:
159
159
  - chunked
160
160
  body:
161
161
  encoding: ASCII-8BIT
162
- string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001LS2EAAW"},"Id":"a001a000001LS2EAAW","SystemModstamp":"2015-04-10T02:10:31.000+0000","Name":"a001a000001LS2E","Example_Field__c":null,"Friend__c":"0031a000001y45eAAA"}]}'
163
- http_version:
162
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001LS2EAAW"},"Id":"a001a000001LS2EAAW","SystemModstamp":"2015-04-10T02:10:31.000+0000","Name":"a001a000001LS2E","Example_Field__c":null,"Friend__c":"0031a000001y45eAAA"}]}'
163
+ http_version:
164
164
  recorded_at: Fri, 10 Apr 2015 02:10:32 GMT
165
165
  - request:
166
166
  method: get
167
- uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Email%20from%20Contact%20where%20Id%20=%20%270031a000001y45eAAA%27
167
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20Email%20from%20Contact%20where%20Id%20=%20%270031a000001y45eAAA%27
168
168
  body:
169
169
  encoding: US-ASCII
170
170
  string: ''
@@ -197,12 +197,12 @@ http_interactions:
197
197
  - chunked
198
198
  body:
199
199
  encoding: ASCII-8BIT
200
- string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"Contact","url":"/services/data/v26.0/sobjects/Contact/0031a000001y45eAAA"},"Id":"0031a000001y45eAAA","SystemModstamp":"2015-04-10T02:10:30.000+0000","Email":"somebody@example.com"}]}'
201
- http_version:
200
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"Contact","url":"/services/data/<api_version>/sobjects/Contact/0031a000001y45eAAA"},"Id":"0031a000001y45eAAA","SystemModstamp":"2015-04-10T02:10:30.000+0000","Email":"somebody@example.com"}]}'
201
+ http_version:
202
202
  recorded_at: Fri, 10 Apr 2015 02:10:33 GMT
203
203
  - request:
204
204
  method: delete
205
- uri: https://<host>/services/data/v26.0/sobjects/Contact/0031a000001y45eAAA
205
+ uri: https://<host>/services/data/<api_version>/sobjects/Contact/0031a000001y45eAAA
206
206
  body:
207
207
  encoding: US-ASCII
208
208
  string: ''
@@ -232,11 +232,11 @@ http_interactions:
232
232
  body:
233
233
  encoding: UTF-8
234
234
  string: ''
235
- http_version:
235
+ http_version:
236
236
  recorded_at: Fri, 10 Apr 2015 02:10:34 GMT
237
237
  - request:
238
238
  method: delete
239
- uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001LS2EAAW
239
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c/a001a000001LS2EAAW
240
240
  body:
241
241
  encoding: US-ASCII
242
242
  string: ''
@@ -266,6 +266,6 @@ http_interactions:
266
266
  body:
267
267
  encoding: UTF-8
268
268
  string: ''
269
- http_version:
269
+ http_version:
270
270
  recorded_at: Fri, 10 Apr 2015 02:10:35 GMT
271
271
  recorded_with: VCR 2.9.3
@@ -38,11 +38,11 @@ http_interactions:
38
38
  body:
39
39
  encoding: ASCII-8BIT
40
40
  string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1429557930126","token_type":"Bearer","instance_url":"https://<host>","signature":"r67C8yGA3MlpIHibA9/5ixX6k3b4vIgUwX+3d1iC3Qs=","access_token":"00D1a000000H3O9!AQ4AQJoC69lofp3.BkQNHdxEquIbjgARO_AQ3LgRth6RSFmB4_KVDLfm9_.J64ouFAGqhXyiThQHypNf.xCD1enx2SQbZDcP"}'
41
- http_version:
41
+ http_version:
42
42
  recorded_at: Mon, 20 Apr 2015 19:25:30 GMT
43
43
  - request:
44
44
  method: post
45
- uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c
45
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c
46
46
  body:
47
47
  encoding: UTF-8
48
48
  string: '{"Friend__c":null}'
@@ -72,7 +72,7 @@ http_interactions:
72
72
  Sforce-Limit-Info:
73
73
  - api-usage=13/15000
74
74
  Location:
75
- - "/services/data/v26.0/sobjects/CustomObject__c/a001a000001MG7WAAW"
75
+ - "/services/data/<api_version>/sobjects/CustomObject__c/a001a000001MG7WAAW"
76
76
  Content-Type:
77
77
  - application/json;charset=UTF-8
78
78
  Transfer-Encoding:
@@ -80,11 +80,11 @@ http_interactions:
80
80
  body:
81
81
  encoding: ASCII-8BIT
82
82
  string: '{"id":"a001a000001MG7WAAW","success":true,"errors":[]}'
83
- http_version:
83
+ http_version:
84
84
  recorded_at: Mon, 20 Apr 2015 19:25:31 GMT
85
85
  - request:
86
86
  method: get
87
- uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Name,%20Example_Field__c,%20Friend__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001MG7WAAW%27
87
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20Name,%20Example_Field__c,%20Friend__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001MG7WAAW%27
88
88
  body:
89
89
  encoding: US-ASCII
90
90
  string: ''
@@ -117,12 +117,12 @@ http_interactions:
117
117
  - chunked
118
118
  body:
119
119
  encoding: ASCII-8BIT
120
- string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001MG7WAAW"},"Id":"a001a000001MG7WAAW","SystemModstamp":"2015-04-20T19:25:31.000+0000","Name":"a001a000001MG7W","Example_Field__c":null,"Friend__c":null}]}'
121
- http_version:
120
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001MG7WAAW"},"Id":"a001a000001MG7WAAW","SystemModstamp":"2015-04-20T19:25:31.000+0000","Name":"a001a000001MG7W","Example_Field__c":null,"Friend__c":null}]}'
121
+ http_version:
122
122
  recorded_at: Mon, 20 Apr 2015 19:25:32 GMT
123
123
  - request:
124
124
  method: get
125
- uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Email%20from%20Contact%20where%20Id%20=%20%27%27
125
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20Email%20from%20Contact%20where%20Id%20=%20%27%27
126
126
  body:
127
127
  encoding: US-ASCII
128
128
  string: ''
@@ -156,11 +156,11 @@ http_interactions:
156
156
  body:
157
157
  encoding: ASCII-8BIT
158
158
  string: '{"totalSize":0,"done":true,"records":[]}'
159
- http_version:
159
+ http_version:
160
160
  recorded_at: Mon, 20 Apr 2015 19:25:33 GMT
161
161
  - request:
162
162
  method: delete
163
- uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001MG7WAAW
163
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c/a001a000001MG7WAAW
164
164
  body:
165
165
  encoding: US-ASCII
166
166
  string: ''
@@ -190,6 +190,6 @@ http_interactions:
190
190
  body:
191
191
  encoding: UTF-8
192
192
  string: ''
193
- http_version:
193
+ http_version:
194
194
  recorded_at: Mon, 20 Apr 2015 19:25:34 GMT
195
195
  recorded_with: VCR 2.9.3
@@ -38,11 +38,11 @@ http_interactions:
38
38
  body:
39
39
  encoding: ASCII-8BIT
40
40
  string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1429810394922","token_type":"Bearer","instance_url":"https://<host>","signature":"qD5Hnlij9mqvLquOno/CQKE+/oNFSOhawRLJvX4MVpE=","access_token":"00D1a000000H3O9!AQ4AQFoglftCDJPkzXd0wAZ6dnUwrMZEyIrpgn8BUhjwsElswNHT_M5IOJSysNJCZXw6QPBjjHcAYLoUX8bFjnXkaUCdvO1l"}'
41
- http_version:
41
+ http_version:
42
42
  recorded_at: Thu, 23 Apr 2015 17:33:15 GMT
43
43
  - request:
44
44
  method: post
45
- uri: https://<host>/services/data/v26.0/sobjects/Contact
45
+ uri: https://<host>/services/data/<api_version>/sobjects/Contact
46
46
  body:
47
47
  encoding: UTF-8
48
48
  string: '{"Email":"somebody@example.com","LastName":"Somebody"}'
@@ -72,7 +72,7 @@ http_interactions:
72
72
  Sforce-Limit-Info:
73
73
  - api-usage=13/15000
74
74
  Location:
75
- - "/services/data/v26.0/sobjects/Contact/0031a000002fBHlAAM"
75
+ - "/services/data/<api_version>/sobjects/Contact/0031a000002fBHlAAM"
76
76
  Content-Type:
77
77
  - application/json;charset=UTF-8
78
78
  Transfer-Encoding:
@@ -80,11 +80,11 @@ http_interactions:
80
80
  body:
81
81
  encoding: ASCII-8BIT
82
82
  string: '{"id":"0031a000002fBHlAAM","success":true,"errors":[]}'
83
- http_version:
83
+ http_version:
84
84
  recorded_at: Thu, 23 Apr 2015 17:33:16 GMT
85
85
  - request:
86
86
  method: post
87
- uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c
87
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c
88
88
  body:
89
89
  encoding: UTF-8
90
90
  string: '{"Friend__c":"0031a000002fBHlAAM"}'
@@ -114,7 +114,7 @@ http_interactions:
114
114
  Sforce-Limit-Info:
115
115
  - api-usage=13/15000
116
116
  Location:
117
- - "/services/data/v26.0/sobjects/CustomObject__c/a001a000001QmhqAAC"
117
+ - "/services/data/<api_version>/sobjects/CustomObject__c/a001a000001QmhqAAC"
118
118
  Content-Type:
119
119
  - application/json;charset=UTF-8
120
120
  Transfer-Encoding:
@@ -122,11 +122,11 @@ http_interactions:
122
122
  body:
123
123
  encoding: ASCII-8BIT
124
124
  string: '{"id":"a001a000001QmhqAAC","success":true,"errors":[]}'
125
- http_version:
125
+ http_version:
126
126
  recorded_at: Thu, 23 Apr 2015 17:33:17 GMT
127
127
  - request:
128
128
  method: get
129
- uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Name,%20Example_Field__c,%20Friend__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001QmhqAAC%27
129
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20Name,%20Example_Field__c,%20Friend__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001QmhqAAC%27
130
130
  body:
131
131
  encoding: US-ASCII
132
132
  string: ''
@@ -159,12 +159,12 @@ http_interactions:
159
159
  - chunked
160
160
  body:
161
161
  encoding: ASCII-8BIT
162
- string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001QmhqAAC"},"Id":"a001a000001QmhqAAC","SystemModstamp":"2015-04-23T17:33:17.000+0000","Name":"a001a000001Qmhq","Example_Field__c":null,"Friend__c":"0031a000002fBHlAAM"}]}'
163
- http_version:
162
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001QmhqAAC"},"Id":"a001a000001QmhqAAC","SystemModstamp":"2015-04-23T17:33:17.000+0000","Name":"a001a000001Qmhq","Example_Field__c":null,"Friend__c":"0031a000002fBHlAAM"}]}'
163
+ http_version:
164
164
  recorded_at: Thu, 23 Apr 2015 17:33:18 GMT
165
165
  - request:
166
166
  method: get
167
- uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Email%20from%20Contact%20where%20Id%20=%20%270031a000002fBHlAAM%27
167
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20Email%20from%20Contact%20where%20Id%20=%20%270031a000002fBHlAAM%27
168
168
  body:
169
169
  encoding: US-ASCII
170
170
  string: ''
@@ -197,12 +197,12 @@ http_interactions:
197
197
  - chunked
198
198
  body:
199
199
  encoding: ASCII-8BIT
200
- string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"Contact","url":"/services/data/v26.0/sobjects/Contact/0031a000002fBHlAAM"},"Id":"0031a000002fBHlAAM","SystemModstamp":"2015-04-23T17:33:16.000+0000","Email":"somebody@example.com"}]}'
201
- http_version:
200
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"Contact","url":"/services/data/<api_version>/sobjects/Contact/0031a000002fBHlAAM"},"Id":"0031a000002fBHlAAM","SystemModstamp":"2015-04-23T17:33:16.000+0000","Email":"somebody@example.com"}]}'
201
+ http_version:
202
202
  recorded_at: Thu, 23 Apr 2015 17:33:19 GMT
203
203
  - request:
204
204
  method: delete
205
- uri: https://<host>/services/data/v26.0/sobjects/Contact/0031a000002fBHlAAM
205
+ uri: https://<host>/services/data/<api_version>/sobjects/Contact/0031a000002fBHlAAM
206
206
  body:
207
207
  encoding: US-ASCII
208
208
  string: ''
@@ -232,11 +232,11 @@ http_interactions:
232
232
  body:
233
233
  encoding: UTF-8
234
234
  string: ''
235
- http_version:
235
+ http_version:
236
236
  recorded_at: Thu, 23 Apr 2015 17:33:20 GMT
237
237
  - request:
238
238
  method: delete
239
- uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001QmhqAAC
239
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c/a001a000001QmhqAAC
240
240
  body:
241
241
  encoding: US-ASCII
242
242
  string: ''
@@ -266,6 +266,6 @@ http_interactions:
266
266
  body:
267
267
  encoding: UTF-8
268
268
  string: ''
269
- http_version:
269
+ http_version:
270
270
  recorded_at: Thu, 23 Apr 2015 17:33:21 GMT
271
271
  recorded_with: VCR 2.9.3