Recently at work I was tasked with making rails work with soap4r. There is a ticket on the soap4r trac[1] and in the Rails trac[2]. There are a wide range of solutions. I personally try to avoid changing core code if I can. With that in mind I have created two solutions.
In both solutions you need to not have soap4r install in the default gem folder. So gem install it in the Rails layout.
#since having soap4r installed will break all rail projects remove it.
sudo gem uninstall soap4r
sudo gem install --install-dir ~/rails_dir/vendor/gems soap4r
You can update the gem and remove it if needed. I see two negatives to this solution. One is that when I run IRB I do not have soap4r. This is solved by having it also installed in the normal gem dir on my dev box. Two there is going to be extra bandwidth with coping your rails code around. This can also be solved by installing it on your production boxes. If you have more then one prod box that could be a pain to remember to do.
Solution 1:
Set the GEM_PATH in the rails project:
Setting gem_path after require rubygems is a great way to keep soap4r in one project. The gem library is to use once you find the documentation. For some reason it is not listed on the ruby-doc website but you should have a local version of the docs.
In your environment.rb file add
ENV['GEM_PATH'] = "#{File.dirname(__FILE__)}/../../../../gems"
require "rubygems"
Gem.clear_paths
or the location you installed the gems to. Then gem install your little hard way.
Solution 2:
Use rubygem classes:
rubygems is just another ruby class to load other ruby classes. Its one of the reasons we are in this mess to begin with. The good news is I have searched for example code and found nothing useful
gems = Gem::SourceIndex.from_gems_in("~/local_gems")
spec = gems.search('soap4r').last
spec.require_paths.unshift spec.bindir if spec.bindir
soap_path = ""
require_paths = spec.require_paths.map do |path|
tmp = File.join spec.full_gem_path, path
soap_path = tmp if tmp.include?("/lib")
tmp
end
sitelibdir = Config::CONFIG['sitelibdir']
$LOAD_PATH.insert($:.index(sitelibdir), *require_paths)
require File.join(path,"soap","soap")
As you can see most of it is just from the gem require process. All I added was the SourceIndex and soap path pieces. This code was my first fix. I tried like heck to set the gem load path but never made the connection to where it was first loading rubygems. This solution fails with requiring a gem, using versions, and preventing the gem from being loaded again. All things that can be fixed but I did not post the code. I am thinking about extending rubygem to allow you say gem name,revision,location.
[1] http://dev.ctor.org/soap4r/ticket/433
[2] http://dev.rubyonrails.org/ticket/10001