class SoqlData
Represents an API interaction via SOQL queries with the Salesforce
database Usually this class is inherited by a class that represents a particular object, the only exception being the singleton methods in 'SoqlGlobalData'
Attributes
@return [String] User used to make api calls
Public Class Methods
Create object using FactoryBot @param [Hash] factory_parameters Parameters to pass to FactoryBot
# File lib/leap_salesforce/soql_data/soql_data.rb, line 73 def self.create(*factory_parameters) FactoryBot.create(to_s.snakecase.to_sym, *factory_parameters) end
Returns descendants of the provided class SoqlData
@return [Class] Classes that inherit from this class
# File lib/leap_salesforce/soql_data/soql_data.rb, line 256 def self.descendants ObjectSpace.each_object(Class).select { |class_name| class_name < self } end
Create a new SoqlData
object. If override_parameters are empty then it's assumed creation of an object is being done
@example Create a new Contact step by step (Contact inherits from this class)
contact = Contact.new contact.first_name = 'Bob' contact.last_name = 'Smith' contact.save! # API request made at this point
@example Create a Contact by specifying field names
contact = Contact.new first_name: 'Bob', last_name: 'Smith' contact.save!
@example Create a contact using a factory with a trait of :email
contact_with_email = FactoryBot.create(:contact, :email)
@example Perform a get to the Salesforce
limits api
SoqlData.new("Limits", method: :get, suburl: 'limits/')
@param [String, Hash] name Name describing object. Defaults to itself. If Hash is provided
with no 'http_parameters' then list will be fields to set on creating entity
@param [Hash] http_parameters Parameters used in making HTTP request. If creating a new object
leave this to empty. Otherwise Hash would look like method: :get, suburl: 'URL_AFTER_SOQL_HANDLER_BASE_URL'
# File lib/leap_salesforce/soql_data/soql_data.rb, line 47 def initialize(name = nil, http_parameters = {}) super if @override_parameters && @override_parameters[:suburl] suburl_passed = @override_parameters[:suburl] @override_parameters[:suburl] = if suburl_passed.include?('sobjects') suburl_passed[suburl_passed.index('sobjects')..-1] else suburl_passed end end return unless http_parameters.empty? table_name = self.class.soql_object_name self.suburl = "sobjects/#{table_name}" optional_name = self.class.to_s == table_name ? '' : "(#{table_name})" self.test_name = "Factory for '#{self.class}'#{optional_name}" unless name return unless name.is_a? Hash name.dup.each do |field_name, field_value| send("#{field_name}=", field_value) end end
Public Instance Methods
@return [String] Value at backend name
# File lib/leap_salesforce/soql_data/soql_data.rb, line 201 def [](backend_name) if @updated successful? unless backend_name.to_s == 'message' || backend_name.to_s == '$..message' @updated = false find # Retrieve data freshly after an update end value_from_path backend_name rescue NoElementAtPath raise diagnose_error if error_message? find value_from_path backend_name end
Set a parameter request in the request body. Can be used to build a request over several steps (e.g Cucumber) Will be used with FactoryBot
@example
exchange['name'] = 'tester' # Will set { name: tester } in the response, formatting as JSON or XML depending on REST / SOAP
@param [String, Symbol] key Name of request element to set @param [String] value Value to set request element to
# File lib/leap_salesforce/soql_data/soql_data.rb, line 194 def []=(key, value) value = value.salesforce_format if value.is_a? Time @override_parameters[:body] ||= {} @override_parameters[:body][key] = value end
Add the passed in file as an attachment to the object
# File lib/leap_salesforce/soql_data/soql_data.rb, line 174 def attach(filename) unless defined? Attachment raise LeapSalesforce::SetupError, 'Attachment not defined. ' \ "Add to '.leap_salesforce.yml' to use this" end raise LeapSalesforce::Error, "Filename #{filename} does not exist" unless File.exist? filename FactoryBot.create(:attachment, ParentId: id, Name: File.split(filename).last, body: Base64.encode64(File.read(filename))) end
Delete current record @param [Boolean] must_pass Whether to raise exception if call is not successful @return [Exchange] Exchange object making delete
# File lib/leap_salesforce/soql_data/soql_data.rb, line 142 def delete(must_pass: false) sf_id = id self.class.delete(sf_id, must_pass: must_pass) rescue NoElementAtPath LeapSalesforce.logger.warn "Tried to delete object that doesn't exist" self end
Delete current record, switching to Admin before doing so @param [Boolean] must_pass Whether to raise exception if call is not successful @return [Exchange] Exchange object making delete
# File lib/leap_salesforce/soql_data/soql_data.rb, line 153 def delete_as_admin(must_pass: true) LeapSalesforce.api_user = LeapSalesforce::Users.where key: :admin rescue LeapSalesforce::UserError raise LeapSalesforce::SetupError, 'Please set up a user with a key of :admin' \ 'to use "delete_as_admin"' else delete must_pass: must_pass end
@return [String, RestClient::Response] Error message if present
# File lib/leap_salesforce/soql_data/soql_data.rb, line 216 def diagnose_error return error_message if error_message? return response if @response # If response is made it would be helpful in diagnosing inspect # If no response, this may help end
@return [String] Error message if present. If not an error is raised
# File lib/leap_salesforce/soql_data/soql_data.rb, line 230 def error_message if error_message? value_from_path :message else message = "No error message received. Status code is #{status_code}. " message += 'Response is successful when it should not be. ' if status_code.to_s[0] == '2' message += 'Response is empty' if response.to_s.empty? raise LeapSalesforce::ResponseError, message end end
@return [Boolean] Whether error message element is present
# File lib/leap_salesforce/soql_data/soql_data.rb, line 225 def error_message? error_message_element? end
Get details of itself by searching for it's id Store response within itself @return [Exchange] Exchange with details of data
# File lib/leap_salesforce/soql_data/soql_data.rb, line 117 def find @response = self.class.find(Id: id).response # Make get call and store result self end
@deprecated Get details of itself by searching for it's id Store response within itself @return [Exchange] Exchange with details of data
# File lib/leap_salesforce/soql_data/soql_data.rb, line 126 def get LeapSalesforce.logger.warn "Method 'get' called when it is deprecated" \ " from #{caller_locations[0]}" find end
Extract the id or return the cached version of it @return [String] Id of Salesforce
Object
# File lib/leap_salesforce/soql_data/soql_data.rb, line 102 def id @id ||= value_from_path '$..id,$..Id' end
@return [Array] List of ids from response
# File lib/leap_salesforce/soql_data/soql_data.rb, line 169 def ids values_from_path('$..Id') end
@param [Boolean] set Whether to not retry for successful response (Used when you expect an error)
# File lib/leap_salesforce/soql_data/soql_data.rb, line 107 def no_retry=(set) return unless set # Set retry_count to 0 so if an invalid status code is returned a retry will not occur define_singleton_method('retry_count') { 0 } end
Open Object
on default browser
# File lib/leap_salesforce/soql_data/soql_data.rb, line 250 def open_on_ui Launchy.open("#{SoqlHandler.instance_url}/#{id}") end
Update current record with data provided expecting success @param [Hash] data Data to update exchange with
# File lib/leap_salesforce/soql_data/soql_data.rb, line 164 def success_update(data) update(**data, must_pass: true) end
@return [True, LeapSalesforce::ResponseError] Whether response is successful
# File lib/leap_salesforce/soql_data/soql_data.rb, line 243 def successful? raise LeapSalesforce::ResponseError, "Error with updating #{self} #{diagnose_error}" unless (200..299).cover? status_code true end
Unsets the element so it's not set in the request at all (not just not setting it to empty) @todo: Allow mapping from ruby created field name to use as a parameter @param [String, Symbol] element_to_unset Element to remove from being sent @param [Boolean] error Whether to raise error if value to unset is not present
# File lib/leap_salesforce/soql_data/soql_data.rb, line 91 def unset=(element_to_unset, error: true) converted_element = element_to_unset.to_s unless @override_parameters[:body].key?(converted_element) && error raise LeapSalesforce::RequestError, "No backend name #{element_to_unset} in #{@override_parameters[:body]}\n" \ "Valid values are #{@override_parameters[:body].keys}" end @override_parameters[:body].delete converted_element end
Update current record with data provided @param [Hash] data Data to update exchange with
# File lib/leap_salesforce/soql_data/soql_data.rb, line 134 def update(data) @updated = true self.class.update(id, data) end