Using a DB is a natural thing for a Rails developer. Since Rails is a database driven application framework, that does not come as a big surprise. But there are times where environmental constraints do not allow the freedom to use the weapon of choice…
Imagine a legacy Java SOA landscape that provides tons of webservices but does not permit access to a transaction DB. Sounds phoney? Ask your local J2EE consultant!
Working around this constraint, it would be great if one could just wire a SOAP service into Rails as a backing of model data. Using Rails without a database is a little bit tricky, especially if you don’t want to forego the power of ActiveRecord!
h2. so why use Rails then?
There are a lot of people that would say “Why don’t you use “Sinatra”:http://www.sinatrarb.com/ instead?”.
First of all, most Ruby developers know how to use Rails. The Rails community is large, lively and a great resource for knowledge. Features like REST come for free and nobody want’s to miss model validations. In general, Rails plugins are lazy programmers best friend!
h2. working with ActiveForm
A simple way to get your SOAP backed noSQL model working with ActiveRecord::Validations is probably by using “ActiveForm”:http://github.com/remvee/active_form. It provides validations for non ActiveRecord models and is available on github.
You can install the Rails plugin via:
# (re)install from git as a plugin
script/plugin install --force git://github.com/remvee/active_form.git
Using the plugin in your code is simple. Inherit from ActiveForm instead of ActiveRecord::Base:
# app/models/blog.rb
class Blog < ActiveForm
column :title
column :message, :type => :text
validates_presence_of :title, :message
[...]
end
It’s possible to remove all evidence of database connectivity. Just kick ActiveRecord from the list of Rails frameworks and re-add it as a gem (this step is not necessary, so you might skip it and work with Rails sqlite3 default):
# config/environment.rb
Rails::Initializer.run do |config|
[...]
config.gem "activerecord", :version => '2.3.5'
[...]
config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
[...]
end
Doing so will allow you to delete the database.yml file in your application.
h2. Savon for multi-tier persistence
Accessing an enterprise SOAP service with “Savon”:http://github.com/rubiii/savon/ is easy and integrating Savon into a Rails model requires just two steps:
* implementing a to_hash method
* implementing a save hook
Since Savon communication is based on data hashes, you have to provide a thin mapping layer to convert your model into a request hash that matches your SOAP interface:
# app/models/blog.rb
def to_hash
{ :data => {:title=>title, :message=>message} }
end
Pushing the data to the webservice requires some custom ‘persistence’ code to be implemented. A good place for that code should be in one of the model’s save hooks:
# app/models/blog.rb
def after_save
client = Savon::Client.new "http://localhost:8080/"
client.post! do |soap|
soap.namespace = "urn:savon:blog"
soap.body = to_hash
end
end
Overwriting the after_save method is a neat way to let the model code be readable for other Rails developers. Sticking to conventions is a best practice and reduces complexity greatly!
h2. more information?
There is a working example using a local “soap4r”:http://dev.ctor.org/soap4r server available on “github”:http://github.com/phoet/savon_nosql_example.
no SQL – no problem!
Pingback: blaulabs » Blog Archive » noSQL – Rails 2 Models mit SOAP