Welcome to ActiveSalesforce SOAP Adapter (asf-soap-adapter)

The “asf-soap-adapter” is based on the ActiveSalesforce-Adapter (classes/ActiveRecord/Base.html and classes/ActiveRecord/ConnectionAdapters/SalesforceAdapter.html). It has been updated to include new methods/APIs from the latest version of the Salesforce Web Services (SOAP-based) APIs. At the time of release, that API is at version 20. Major features:

  1. Removed hardcoded version of v19, v18, etc in the code. Now, you just specify it in the ‘database.yml’ file with ‘api_version’. By default it is at 20.0

  2. Adding RForce GEM as a prerequisite. By removing embedded RForce 0.4.0 files, we can now taken advantage of RForce 0.4.1 GEM, which is cleaner and addressed several problems with Hash. One thing to note: if you are using RFORCE:MethodHash class. It has been been replaced by <OpenHash> class. To use it, simply call OpenHash.new({}) in place of MethodHash. Previously, there was a bug with the MethodHash class causing Id to be put into an array, e.g. FeedPost.Id, even though there was only one element. So, now it is FeedPost.Id.

  3. Adding several useful Salesforce convenience classes, which is under Saleforce module. You can use Salesforce::Account, Salesforce::User, etc. This frees you from having to create Ruby Models in your application, which can be in a pain, if you using Rails db generation tools, e.g. Hobo, which checks to see if you have a database table for that class. With these convenience classes, you are no longer required to create those tables.

  4. Support for Chatter newsfeeds. Retrieving Chatter Feed has always been difficult. There are several challenges. First, you can not select directly from the FeedPost, FeedTrackedChanges, and FeedComments tables. That means you always needed to put that in a subquery, as: SELECT Id, Type, (FeedPost.ID, FeedPost.Body, FeedPost.ContentType, et.… ), (Select Id, FieldName, OldValue, NewValue from FeedTrackedChanges), (Select Id, CommentBody, .… from FeedComments) form feed_typeFeed where parentid=‘#####’. Doing that over and over again can be repetitive and against the DRY (Don’t Repeat Yourself) principle of Rails programming. Therefore, a convenience class has been provided from you. see Salesforce::ChatterFeed. See following example.

    chatter_feed_finder = Salesforce::ChatterFeed.new
    # The following two lines shows how to get the account_feed.id. You can replace it with your
     = Salesforce::AccountFeed.first
    object_id = .id
    feed_no_attachment = chatter_feed_finder.get_all_chatter_feeds_without_attachments(object_id, 'Account', user.connection.binding, 'test-session-id')
    

Furthermore, the syntaxes from the methods are:

chatter_feed_finder.get_all_chatter_feeds_with_attachments(object_id, object_type, binding, directory_name, limit, get_attachment)
chatter_feed_finder.get_all_chatter_feeds_without_attachments(object_id, object_type, binding, directory_name, limit)
chatter_feed_finder.get_single_chatter_feed_with_attachment(feedpost_id, feed_type, binding, directory_name, limit)

where,

object_id -> id of the feed
object_type -> type of feed, e.g. AccountFeed, CampaignFeed, ContactFeed, UserFeed, ....
binding -> the RForce binding used to for connecting to Salesforce Web Services Server
directory_name -> where the attachment will be saved at, it is stored under the RAILS_ROOT/public/tmp/{your directory}
limit -> max of number of feed retrieved which this call
get_attachment -> boolean flag: yes (get attachment), no (don't get attachment)
  1. Salesforce Object lookup utility, provide a Salesforce object Id, and figure out if it is an Account, User, Lead, etc. Salesforce::SfUtility.determine_sf_object_type(id). See the document for other useful method in this class.

  2. Ability to call non-traditional SQLs. e.g. with “LIMIT”, “GROUP BY”, “HAVING”, and “WITH DATA CATEGORY”. example:

    another = Salesforce::SfBase.query_by_sql("SELECT LeadSource, COUNT(Name) FROM Lead GROUP BY LeadSource")
    assert another.size
    
  3. more .…

    zero_result = Salesforce::SfBase.query_by_sql("SELECT Name, Count(Id) FROM Account GROUP BY Name HAVING Count(Id) > 100")
    assert_nil zero_result
    
  4. The best part, is this gem is backward compatible with the original ActiveSalesforce-Adapter GEM release. You only need to make minimum changes to your application to use this GEM. To use this gem, simply replace the declaration in config/environment.rb with config.gem “asf-soap-adapter”, :lib => “activerecord-activesalesforce-adapter” in the Rails::Initializer.run do |config| section.

Significant Changes

  1. Detached hardcoded RForce 0.4.0 and replaced with RForce 0.4.1 gem.

  2. Dynamic Adapter version from ‘database.yml’ file via ‘api_version’ parameter

  3. Conveninence classes, Salesforce::Account, User, .…

  4. Chatter Feed

  5. Object Lookup Utility (SF id -> SF object type)

  6. Nontraditional query support

Installation

  1. Add: config.gem “asf-soap-adapter”, :lib => “activerecord-activesalesforce-adapter” to Rails::Initializer.run do |config| section in your config/environment.rb file.

  2. run sudo rake gems:install from your rails base directory.

Getting started

  1. If you have not already done so generate your initial rails app:

    rails myappname
    
  2. Edit config/environment.rb and add a config.gem requirement:

    Rails::Initializer.run do |config|
      ...
      config.gem "asf-soap-adapter", :lib => 'asf-soap-adapter'
      ...
    end
    
  3. Edit database.yml

salesforce-default-realm:

adapter: activesalesforce
url: https://www.salesforce.com
username: <username>
password: <password + security token>
api_version: 20.0

NOTE: "url" is an optional parameter.  If you want to access your Salesforce Sandbox account add the following line.   
  url: https://test.salesforce.com
      "api_version" is also optional. If you don't specify a version, it is automatically default to 20.0.
  1. Create your salesforce models using a Salesforce::<ModelName> namespace.

    A lot of the Salesforce Models have already been provided as convenience class. If you need to add more:

    script/generate model Salesforce::NewObject
    
    update the file
    

module Salesforce

# See http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_list.htm
# For complete list of Salesforce Standard Objects in V20.
class NewObject < SfBase
  set_table_name 'NewObject' # must be a valid Salesforce Table, otherwise, it will complain.
end

end

  1. Run a quick test to make sure things are working

    > script/console
    Loading development environment (Rails 2.3.9)
    
    >> Salesforce::Contact.first
    => <Salesforce::Contact id: "003T000000GqvJsIAJ", ... >
    
  2. Proceed using standard Rails development techniques!

Advanced Features

  1. Session ID based Authentication: Add the following to /app/controllers/application.rb to enable SID auth for all controllers

    class ApplicationController < ActionController::Base

    before_filter ActiveSalesforce::SessionIDAuthenticationFilter
    

    end

  2. Boxcar’ing of updates, inserts, and deletes. Use <YourModel>.transaction() to demark boxcar boundaries.

Description of contents

lib

Application specific libraries. Basically, any kind of custom code that doesn't
belong under controllers, models, or helpers. This directory is in the load path.
-- active_record   -> asf model
-- salesforce      -> convenience classes and utilities

test

Unit and functional tests along with fixtures. See enclosed test app (asf-soap-adapter-rails-app) for full-fledge tests.

Additional Note:

The enclosed test app (asf-soap-adapter-rails-app) shows how to use the framework. Go into its “test/unit” directory, where examples are provided.

I am currently, updating my reference app SFRWatcher to SFRWatcher_v20 to match the switch from the old gem to this new gem. Once it is ready, it will be posted on the web soon. The project home: asf-soap-adapter.are4.us

Copyright © 2010 Raymond Gao. See LICENSE for details.