Monday, June 23, 2014

Faraday::SSLError certificate verify failed

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

In recent memory, this is easily the most frustrating error I've had to troubleshoot. I needed SSL to work so that I could establish secure communication between Salesforce and my Rails app on Heroku. Unfortunately, neither Heroku's sample Ruby (off Rails) app nor general OmniAuth documentation seemed to give any insight into the error or how to resolve it.

Piecing together bits of knowledge gleaned from Google searches, I eventually arrived at the following solution for Rails development on Windows 8:

  • Download root certificates in PEM format
  • Set an environment variable called CA_FILE, pointing to the downloaded PEM file
  • Create an omniauth.rb initializer file, as suggested by OmniAuth
  • Specify the :client_options hash value for the :salesforce provider, as shown below

I know I'm going to run into this error again in the future, and hopefully this blog post will help me and hopefully others resolve the problem in the most secure and supportable means available.


初めて日本語でブログ投稿ですから、いろいろな文法的と文化的のミスしてしまって申し訳ありません。下記のコンテンツは「Controller Component Communication」の翻案です。






Wednesday, June 18, 2014

Rails directories for Heroku Connect

Heroku Connect is a new add-on offering that simplifies data synchronization between Heroku apps and Salesforce. At its core, Heroku Connect periodically syncs selected objects and fields between Salesforce and Heroku. While the demo Rails app provided by Heroku gives a solid recommendation for extending ActiveRecord::Base to create an analog for models in the Heroku Connect database, some gaps still existed in terms of how to best set up your Rails app and define your classes.

After some experimentation, I decided on the following setup for my app:

  • Heroku Connect model paths: app/models/heroku_connect/schema_name/table_name.rb
  • HerokuConnectRecord::Base
  • Autoload lib modules and classes

I'll explain the setup in more detail below, but quick question: How would you set up your Rails app directories for Heroku Connect?

Heroku Connect model paths

All models in your Rails app by default go in the app/models/ directory. Rails knows to autoload models stored in the models/ directory, and as a result it seemed to reason that Heroku Connect models should go in the same directory. But a namespace is needed to prevent conflicts between regular Rails models and Heroku Connect models. And moreover, what if you have multiple Heroku Connect databases in play?

My implementation addresses this by first moving Heroku Connect models into its own namespace a la the heroku_connect/ directory. Next, different Heroku Connect databases can be split by the schema name or some other unique identifier for each database.

Examples of Heroku Connect model class paths, assuming the schema name "salesforce"
sObject NameClass NameModel Path

Note: For custom object models, the double-underscores can be written as-is in the name of the .rb file. To be more technical, use the String.underscore method in irb to derive the expected name of the model's .rb file. For example, JointVenture__c would become "joint_venture__c.rb", and Lazy_Boy__c would become "lazy_boy__c.rb".


Heroku recommends extending ActiveRecord::Base to create a base for all Heroku Connect models. I thought that instead of calling my base class SalesforceBase, I would call it HerokuConnectRecord::Base to be mimic the naming convention for ActiveRecord::Base. While there's no direct need for this to get going, I figured I would adopt this convention in case I need to extend other Active__ modules or classes down the road for Heroku Connect.

All that's needed to set up this class is the following code, placed within lib/heroku_connect_record/base.rb:

module HerokuConnectRecord
  class Base < ActiveRecord::Base
    self.abstract_class = true
    establish_connection ENV['DATABASE_URL']

All Heroku Connect module classes would then extend this class, as in:

module HerokuConnect
  module Salesforce
    class Car__c < HerokuConnectRecord::Base
      self.table_name = "salesforce.car__c"

Autoload lib modules and classes

Finally, to autoload HerokuConnectRecord::Base (and potentially future custom classes for Heroku Connect), I adopted ifyouseewendy's recommendation to add the following line to config/application.rb:

config.autoload_paths += %W(#{config.root}/lib)

Tuesday, June 10, 2014

Auto External ID for Multi-Partner Integrations

Some companies need to integrate with multiple partner systems, each having its own set of unique identifiers. When you only have one or two of these external identifiers to manage, you can get away with setting up system-specific External ID fields. But happens when you trying to integrate with more than two such systems?

To make things worse, sometimes you have legacy ERP systems (e.g., in the higher education industry) that don’t have unique identifiers stored in a single field. Instead they use inferred keys derived from combinations of other fields.

In lieu of implementing a full MDM solution, one option to easily set up and manage these external identifiers can be to create just three components in Salesforce for each object: two fields and a workflow rule.

Auto External ID

The Auto External ID field is a Formula (Text) field that produces the string that represents the expected, globally unique external identifier. For example, the field could be a concatenation of two other values that produces something like “001154-900100203”.

Having this field also enables administrators to easily troubleshoot problems with the External ID value by comparing the expected identifier with the actual identifier.

{!ObjectLabel} External ID

The {!ObjectLabel} External ID field is a simple Text field configured to be a unique external identifier. The intent is that the Auto External ID value will always be stored in this field, so that DML operations via API’s can match on this field.

The {!ObjectLabel} part of this is simply a recommended labeling convention that helps your field look more like an out-of-the-box Salesforce field.

Set {!ObjectLabel} External ID

Finally, the Set {!ObjectLabel} External ID workflow rule should be configured to fire only when the Auto External ID and the actual External ID values do not match. This way, you avoid having a workflow rule that continuously edits a field blindly even when there is no need to update the field.

The workflow rule makes use of a simple field update that just sets the External ID field to the Auto External ID value.

And that’s all there is to this pattern! Now you can quickly create external identifier fields that are consistently derived and simple to troubleshoot.