This article provides the configuration steps and code to build a Ruby on Rails application deployed on Heroku that uses the Force.com Toolkit for Ruby to connect to the Force.com platform. While Getting Started with the Force.com Toolkit for Ruby gets you up and running and connecting to Force.com, this article provides deeper examples specific to Heroku, in particular providing examples and configuration details - including a complete example of a Rails app running on Heroku that connects to Force.com to retrieve a list of contacts.
Let's look at how to create a simple app, set up your environment, Bundler and routes.
Before getting started, please make sure you follow Getting Started with the Force.com Toolkit for Ruby. This will set up your local machine with the appropriate gems for connecting to Force.com. We are going to use these gems, and modify the configuration steps to allow us to deploy our app to Heroku. Once you have completed the steps up until the Testing the Toolkit section, we can continue.
Alright, you have read the Getting Started Guide. You now have a basic understanding on how to configure the toolkit. Let's take that knowledge and expand it to work with Heroku. Go ahead and create a new Rails project:
With our basic app created, let's configure our app to use Bundler to manage gem dependencies. Bundler is also key for deploying applications to Heroku with the best practice of including all your dependencies in the slug file.
Builder relies on a file,
Gemfile, contained within your application's root dir. You can add specific project dependencies here. You will need to create this file, and then add the following line to bundle in all standard dependencies. Remember we are going to deploy to Heroku soon and need to make sure all our dependencies are available in the cloud.
While we have the
Gemfile open, let's add a line to tell the Bundler that our app requires a versioned dependency for Rails, and another line for a Ruby Toolkit requirement, facets. Your gem file should now look like this:
source :rubygems gem 'rails', '2.3.8' gem 'facets', '2.8.4'
With our Gemfile created and saved, open up the trusty command line and enter the following command from within the
helloforcedotcom directory to run the bundler.
We obviously want some sort of UI to view our data from Force.com. Let's add a controller and a simple view. We will use this controller to retrieve data from Force.com later, but for now it will be pretty empty. From a command line, enter the following:
ruby script/generate controller home index
That's it. Rails just generated a number of files including
app/views/home/index.html.erb and an index action in the
home controller. You can check out the code created by the generate command and see the simplicity of Ruby. Open the
app/controllers/home_controller.rb file for example. You should see something like the following:
class HomeController < ApplicationController def index end end
What this code is telling us is there there is a method called index. By default the method is empty but it will automatically handle routing to the
index.html.erb view just by naming definition. Nice, isn't it.
The last thing we want to do is remove the default home page for our app to ensure users are presented with our
index.html.erb file instead of index.html. From the command line, within the
helloforcedotcom directory, enter the following command:
Once the index.html file is removed, we need to tell our app what controller is our default. You can change a Rails apps routes (the paths to controller and views) in
app/config/routes.rb. Simply scroll down to approximately line 34, and change the map.root value to the following:
map.root :controller => "home"
From your favorite editor (I use TextMate on the Mac, and typically create a project by adding existing files to my *workspace*. In this instance I would add the helloforcedotcom folder) edit
app/views/home/index.html.erb to say something witty like:
We will update this file shortly to display a list of Contact records from Force.com.
Let recap what we have done. Up until this point everything has been pretty well the same as a local Rails app, and the steps covered in the Getting Started Guide. The only additional step we have added is the use of Bundler. Next we will start updating our configuration to support deployment to Heroku.
At the time of writing, the new asf-soap-adapter provided in the Ruby toolkit relies on the previous adapter when deployed to Heroku. As a result, in addition to adding the
config.gem reference in your environment.rb file as detailed in the Getting Started Guide, you also need to add a reference in your
gem 'asf-soap-adapter', :require => 'activerecord-activesalesforce-adapter'
Gemfile, and from the command line, run
Database configurations are contained in
config/database.yml by default. When deploying applications to Heroku, Heroku generates a database.yml for you to connect to Postgres. We want to connect to Force.com though. Let's create a new .yml file in the config directory called
salesforce.yml, and add the following configuration. Heroku requires a
production environment specified, and the toolkit requires an environment called
salesforce-default-realm. In order to centralize our config we can leverage the ability to include common attributes to make maintenance easier going forward:
common: &common adapter: activesalesforce url: https://www.salesforce.com username: [your force.com username] password: [force.com password + token] api_version: 20.0 development: <<: *common production: <<: *common salesforce-default-realm: <<: *common
Now that we have our new .yml file, we need to tell our rails app to load this configuration. Edit your
config/environment.rb and add the following line directly after the
config.gem line you added as part of the Ruby Toolkit setup:
config.database_configuration_file = File.join(RAILS_ROOT, 'config', 'salesforce.yml')
Once complete, your
environment.rb file should look like this:
# Be sure to restart your server when you modify this file # Specifies gem version of Rails to use when vendor/rails is not present RAILS_GEM_VERSION = '2.3.8' unless defined? RAILS_GEM_VERSION # Bootstrap the Rails environment, frameworks, and default configuration require File.join(File.dirname(__FILE__), 'boot') Rails::Initializer.run do |config| config.gem "asf-soap-adapter", :lib => 'asf-soap-adapter' config.database_configuration_file = File.join(RAILS_ROOT, 'config', 'salesforce.yml') config.time_zone = 'UTC' end
That's it. Our application is configured. You can test it locally using the Rails console with the following commands:
And if everything is configured correctly, you should be presented with data:
-> <Salesforce::Contact id: "003T000000GqvJsIAJ", ... >
Next, we are going to add a little logic to our Controller we created earlier, then deploy it to Heroku.
With our adapter configured, we are going to update our controller to perform a query against Force.com to retrieve the id, first name, and last name of the first 100 Contacts. Let's jump in.
Using your favorite editor, open
app/controllers/home_controller.rb and add the following lines of code:
def index sql = "select id, FirstName, LastName from Contact limit 100" @contacts = Salesforce::SfBase.query_by_sql(sql) end
The code above performs a very simple query against the Force.com database returning a list of contacts and assigning them to the
Now we have our collection of contacts, we want to display them on a page. Edit the
app/views/home/index.html.erb file adding the following code to loop through and display the contacts.
<h3>Existing Contacts</h3> <p> <% @contacts.each do |contact| %> Hello <b><%= contact.FirstName %> <%= contact.LastName %> </b> <br/> <% end %> </p>
Ok, our application is all complete. All we need to do is add it to Git and push it to Heroku. The process is very simple. Here's what you have to do.
The first step to deploying our app to the cloud is to create a Heroku account, and install the Heroku gem. By now, you are a RubyGems ninja and know all you need to do is run the following command:
sudo gem install heroku
With Heroku installed, we want to make things secure. SSH is the key here. (sorry I couldn't avoid the pun!) The Heroku docs, give a good walk through on how to set up your SSH keys and add them to Heroku so you can use them with Git to push your code.
Now we have our basic app running on our local machine, and initial Heroku setup out of the way, it's time to get our code into Git. You should have already installed Git as part of the installing the Ruby toolkit for Force.com, but if you haven't used Git before, in a nutshell, it is a distributed version control system perfectly designed for collaborative development on the web. Oh, and Git works amazingly well with Heroku. Who could ask for more!
Let's quickly double check Git is installed and setup correctly. Go ahead and open a terminal and type the following command. If you receive a version number in response, you are ready to go.
Once Git is installed, open your terminal window and change directories to our application,
helloforcedotcom, if you are not there already, then enter the following commands:
git add .
git commit -a
Add a comment such as "adding application for the first time" and continue.
Great. Your app is now in Git. I told you it was easy.
Next, we need to tell Heroku about our app. From the command line, enter the following:
The Heroku create command creates a unique app name on Heroku, usually something whimsical and fun like
simple-sunset-1234. Unfortunately, this is not always what you want. If you want to add a specific app name you can execute the following command:
heroku create yourappname
For our sample app, I'm going to be really creative and call it
helloforcedotcom. Assuming your app name is unique, the create command will give you a response similar to the following:
The very last thing which we need to do is push our application up to Heroku. This is where Git shines. From your terminal, enter the following command. This command is instructing Git to push the master branch of our app to heroku. This is the incredible power and simplicity of Heroku at its finest. Don't blink, you are now deploying to the cloud!
git push heroku master
If everything goes well, you should be presented with something similar to the following:
It's payoff time, go ahead and open a browser and enter your URL. For example, http://helloforcedotcom.heroku.com. You could alternatively use the handy
heroku open command from your terminal to do it for you.
If everything worked as planned you should be presented with the a web page similar to the following which displays a list of Contacts from Force.com:
Congratulations. You have now created an application deployed on Heroku which uses the Ruby Toolkit for Force.com to connect to Force.com and display a list of Contacts. Not bad!
Things have a habit of going wrong right when you don't want them to. If you were developing locally you would typically look at the stack trace in your web servers output log. Don't worry, Heroku provides similar functionality to access the remote logs. Simply enter the following command. (Note: I have added the --appname parameter to this command to refer to my app. It's good practice to get in the habit of naming your apps with meaningful names; It just makes life easier, although Heroku is smart enough to know which app your are working on depending on the directory you are in.)
heroku logs --app helloforcedotcom
Of course, if log files aren't your thing, why not open up an interactive console to your remote app:
heroku console --app helloforcedotcom
This article provides the configuration steps required to build Ruby on Rails applications that use the Force.com Toolkit for Ruby, and deploy them onto Heroku. We started with with a simple Rails app, updated the configuration files, and included a simple controller to fetch a list of data from Force.com. While this application was simplistic in its function, it is valuable to have a clean sample application to build upon.
With a basic understanding of Git and Heroku, you can quickly deploy your application into the cloud, and if desired, collaborate with other team members. By leveraging the toolkit, Ruby developers can also code in a fashion which they are already comfortable with, eliminating the need to learn new syntax or protocols for connecting to your data in the cloud.
Quinton Wall is a Sr. Developer Evangelist at Salesforce.com, and an aspiring fantasy author. He is a regular speaker at cloud and developer events around the world, active contributor to the developer blogs, and twittersphere. When he is not working with the Force.com platform, or writing books, you can find him on the web.