I am not a Ruby guy, but last few days i had to look into this language, moreover in the context of calling apex web service method using Ruby. I love doing this using java and php, even i did in python also, but this time its a challenge for me to achieve this. Its a challenge because lack of documentation and sample codes on net and as a newbie in Ruby world. As every new developer i also searched many times on net but was struggling sometimes setting up Ruby, sometimes rubygems, sometimes things were not working. I left many times work in middle long before also. But searching and searching and i found this blogpost by Andrew very helpful. http://hideoustriumph.wordpress.com/2008/05/05/ws-deathstar-for-the-rest-of-us/.
So most of the things i took from that blog only and here i am describing some sample code how i achieve my task.
1) You first need to install ruby. I had InstantRails 2.0. That fits my need.
2) Now first go to your developer account, Setup->Develop->API, choose "enterprise.wsdl" and save it somewhere on your disk , for example in my case i am saving it as below location.
D:\RubyRails\rails_apps\sfdc\enterprise.xml
3) Open the ruby console
4) Then you need to install "SOAP4R" by this command.
gem install soap4r
When i ran this command, i got errors like "Errno::EADDRNOTAVAIL". Its because my gems were outdated, if this is the same case with you then you need to install first updated gems. so...
5) go to this site http://rubygems.org/pages/download
6) Download the gems and unpack to a directory and go to that directory from the command line
7) Install with:
ruby setup.rb
8) Now issue the command to install soap4r
gem install soap4r
Hopefully this time it will get installed.
9) Now go to that directory where you saved the "enterprise.xml" from command line and issue following command.
ruby wsdl2ruby.rb --wsdl D:\RubyRails\rails_apps\sfdc\enterprise.xml --type client --force
You will see 4 files created into your current directory ('sfdc' in above case)
10) Now here is the code for one extra file which i copied from the above blogpost for easy login
client_auth_header_handler.rb
--------------------------------
require 'soap/header/simplehandler'
class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler
SessionHeader = XSD::QName.new("rn:enterprise.soap.sforce.com", "SessionHeader")
attr_accessor :sessionid
def initialize
super(SessionHeader)
@sessionid = nil
end
def on_simple_outbound
if @sessionid
{"sessionId" => @sessionid}
end
end
def on_simple_inbound(my_header, mustunderstand)
@sessionid = my_header["sessionid"]
end
end
11) And now here is the final code for doing Login, fetching records from Account object and Printing raw output on screen. Change the username, password and security token as needed.
test.rb
--------------------------------
require 'rubygems'
gem 'soap4r'
require 'soap/soap'
require 'defaultDriver'
require 'client_auth_header_handler'
require 'soap/wsdlDriver'
d = Soap.new
d.wiredump_dev = STDOUT
h = ClientAuthHeaderHandler.new # Create a new handler
l = d.login(:username => "USERNAME", :password => "PASSWORD" + "SECURITY_TOKEN")
d.endpoint_url = l.result.serverUrl # Change the endpoint to what login tells us it should be
h.sessionid = l.result.sessionId # Tell the header handler what the session id is
d.headerhandler << h # Add the header handler to the Array of headerhandlers
d.getUserInfo("")
d.query(:queryString=> "select id,name from account")
12) For test the above code, go to ruby console, go to "sfdc" folder and issue following command.
ruby test.rb
13) Now, the main task for which i struggled and not found any easy code on net. Calling apex method from ruby. I tried different things and thought it might be of few lines but may be complex. But finally after so many hit and trial i found that, the code is really very small and easy enough.
14) For example, lets say i want to make one webservice method in Apex to just print one greeting message on screen to passed one Name param. Create one apex class like this.
MyService.cls
--------------------------------
global class MyService{
webservice static string printMe(string name){
return "Hello " + name;
}
}
D:\RubyRails\rails_apps\sfdc\service\myservice.xml
16) Now here is the complete code to invoke the "printMe" method, for calling this you also need login first, so the complete example is as below.
test.rb
------------------------------------------------
require 'rubygems'
gem 'soap4r'
require 'soap/soap'
require 'defaultDriver'
require 'client_auth_header_handler'
require 'soap/wsdlDriver'
d = Soap.new
d.wiredump_dev = STDOUT
h = ClientAuthHeaderHandler.new # Create a new handler
l = d.login(:username => "USERNAME", :password => "PASSWORD" + "SECURITY_TOKEN")
d.endpoint_url = l.result.serverUrl # Change the endpoint to what login tells us it should be
h.sessionid = l.result.sessionId # Tell the header handler what the session id is
d.headerhandler << h # Add the header handler to the Array of headerhandlers
client = SOAP::WSDLDriverFactory.new( 'service/myservice.xml' ).create_rpc_driver
client.wiredump_dev = STDOUT
client.headerhandler << h
result = client.printMe(:name => "Aslam Bari");
17) If all goes well, you will see raw xml output on console printed.
18) Now its time to explore more in your Ruby skills with SFDC :)
Thanks
Aslam Bari