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.
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)