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 Name | Class Name | Model Path |
Car__c | HerokuConnect::Salesforce::Car__c | app/models/heroku_connect/salesforce/car__c.rb |
OpportunityLineItem | HerokuConnect::Salesforce::OpportunityLineItem | app/models/heroku_connect/salesforce/opportunity_line_item.rb |
AssessmentPeriod__c | HerokuConnect::Salesforce::AssessmentPeriod__c | app/models/heroku_connect/salesforce/assessment_period__c.rb |
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".
HerokuConnectRecord::Base
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']
end
end
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"
end
end
end
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)