www.flickr.com
Michael Kovacs' photos More of Michael Kovacs' photos
Recommend Me Cable Car Software logo

Thursday, December 03, 2009

Rails realities part 29 - Salesforce and rails integration, the easy way

In honor of Dreamforce and RubyConf both being in San Francisco at the same time a couple of weeks ago today's post is about making the two of them work together.
If you do ever need to integrate Salesforce.com with your rails app there's really one game in town, (well really two but one depends on the other, you'll see shortly) and while it works great once you get things working I think the documentation around the process could use a little help so today we're going to have a little tutorial and go through the process of integrating Salesforce into an existing rails application.

So first off the assumptions:

  1. You have a rails 2.3.x app (I'm sure this works with older 2.x versions but for my app I'm running 2.3.4 to be exact)

  2. You'd like to integrate with Salesforce but the entirety of your app is not driven by Salesforce.


What are your options? Well there are currently two projects that seem to be the default and have the most momentum for connecting to SF:
  1. rForce - A simple 'low level" API access library to get at your SF data.

  2. ActiveSalesforce - An ActiveRecord extension that allows you to interact with your SF data using model objects. It uses rForce to make the API calls.


rForce is really simple to use and makes the assumption that you are familiar with the SF API. There's a great tutorial here on how to get that up and running:

http://oldfartdeveloper.blogspot.com/2009/09/rforcesalesforce-setup-for-dummies.html

That's the article that got me "unstuck" trying to figure out my way through the world of Salesforce integration. If you'd like to get up and running with rForce have a look at that tutorial. If you're interested in ActiveSalesforce read on....

So if you didn't read old fart's tutorial above and create a SF developer account then you're gonna wanna do that before we get started. The short of it is:

  1. Go to http://developer.force.com/ and sign up


  2. You will receive an email with your username (Your email address is your username) and a temporary password.


  3. Either click on the embedded link in the email to login or visit https://login.salesforce.com/ and login from there with your email and password. (Once logged in you'll want to change your password to something more memorable than the random string that was generated for you)


  4. Once you've logged in you're taken to the home page of your personal CRM sandbox. At the top of the page you'll want to click on the "Setup" link.




  5. Now we have to obtain your security token that's used to login to the API. To do that click on the "Setup" link at the top of the page.


  6. Once on your setup page you should see a section on the left side navigation titled "Personal Setup". In that section there's a node named "My Personal Information". Expand that node. You should see something like this:



  7. Click on the "Reset Security Token" button to have Salesforce send you an email with your security token.


Once that's completed we're ready to dig into some ruby and get our application talking with the API.

Let's get started!

  1. First let's add a configuration entry in environment.rb in our rails app for the activesalesforce gem. I'm using the johnreilly version on github.
        config.gem "johnreilly-activerecord-activesalesforce-adapter", 
    :lib => 'activerecord-activesalesforce-adapter', :source => 'http://gems.github.com'

  2. Once you have that entry in your environment.rb file you can install the gem by running the following rake command from the root of your application
    sudo rake gems:install

  3. OK so let's create our first SF related model, a base class that will be used for all SF model classes. So we generate:
    ruby script/generate model Salesforce::SfBase

    After that is generated we add some code to connect to SF and end up with something like the following:
    class Salesforce::SfBase < ActiveRecord::Base  
    self.abstract_class = true
    # create a connection to Salesforce for the given user
    def self.login(user, pass, token)
    params = {:adapter => "activesalesforce",
    :url => "https://login.salesforce.com/services/Soap/u/16.0",
    :username => user,
    :password => pass + token}
    self.establish_connection(params)
    end
    end


  4. Next let's generate an SF class that represents a user.
    ruby script/generate model Salesforce::User

    Modify that newly created user class to look as follows:
    class Salesforce::User < Salesforce::SfBase
    end


  5. Now we're ready to test our connection to SF and retrieve a user in their system via the API. Let's create a test in the Salesforce::UserTest as follows:
    class Salesforce::UserTest < ActiveSupport::TestCase
    def test_should_return_sf_user
    user = 'yourSFemail@yourdomain.com'
    password = 'yourSFpassword'
    key = 'your SF security token'
    Salesforce::SfBase.login(user, password, key)
    u = Salesforce::User.first
    assert_not_nil u
    end
    end

    If all went well you should see a successful test run and have a user from the SF system. The code simply logs into SF via the login method defined in our base class. This sets the connection for any ActiveRecord classes that derive from SfBase for the rest of the request. Then we simply use our SF User class the same way we would any ordinary ActiveRecord class.
    As a side not you'll probably want to store the SF credential information in a config file somewhere or if your SF support is on a per user basis somewhere in your users or accounts table.


  6. Extra credit: You can also use related objects in the standard ActiveRecord way as well. For example we could change our User class as follows:
    class Salesforce::User < Salesforce::SfBase
    has_many :contacts, :class_name => "Salesforce::Contact", :foreign_key => 'owner_id'
    has_many :cases, :class_name => 'Salesforce::Case', :foreign_key => 'owner_id'
    end

    Having these relations defined allows us to use relations in the normal rails way:
    user = Salesforce::User.first
    user.contacts
    user.cases

    Of course we'll need to generate a Salesforce::Contact and Salesforce::Case class but you get the idea. ActiveSalesforce will automatically match up any of the built in classes with your properly namespaced salesforce class. The key is that your classes do need to be namespaced at "Salesforce::" as far as I know. Perhaps you can override that behavior but I found it to be exactly what I'd want to do myself.


That should do it. Easy integration of Salesforce as another data source into your existing rails app. I should point out that this is not production tested code so it should be pointed out that things like ensuring the connection to Salesforce isn't causing any leaks should be investigated before deploying to production.

Enjoy!

This page is powered by Blogger. Isn't yours?