Tuesday, April 14, 2009

Rails foreign key assignment and belongs_to associations

I keep getting bitten by some odd behaviour in the way Rails handles assignment to the foreign key attribute of a belongs_to association. Specifically, assigning the foreign key id directly, as one might do when processing a form submission with mass attribute assignment, only works for new records or records where the belongs_to association has not already been loaded.

There's a long-standing ticket for this issue here, but little progress seems to have been made in resolving it.

Frankly, this is a pain in the ass. I wasted a ton of effort on trying to workaround this problem, finally resorting to monkey patching ActiveRecord, which then broke when we tried to upgrade our application to Rails 2.2.2.

On another trip on the merry-go-round this morning, I got lucky and finally spotted a solution that I'd missed before. While others were debating the merits / demerits of various patches and whether all cases were adequately covered, Matt West who opened the ticket, provided a fix in the form of a plugin:

http://code.torchbox.com/svn/rails/plugins/belongs_to_synchronisation/

Unfortunately, it was hidden in a blog post linked from the ticker. See the original blog post here.

Monday, March 30, 2009

How not to implement a web service using SOAP.

Twice in the last six months, I've been faced with implementing a client for a SOAP-based web service. On both occasions there's been a distinct lack of sunshine and rainbows.

After the initial optimism ("this should be easy - it uses SOAP") faded, things went downhill fast. It's an anti-pattern that I expect to see again soon.

The initial exploratory exchange for getting two systems talking over web services, typically goes something like this:

Our Business People: "We'd like our Fobniculator system to be able to talk to your FooBarWidget web application so that going forward we leverage the synergies to bring about a positive sales variance."

Their Business People: "Sure! We'll get our nerds to talk to your nerds."

Some considerable time passes...

Me: "What platform is your FooBarWidget web application built on?"

One of Their nerds: "VB.NET. What about your Fobniculator system?"

Me: "Ruby on Rails."

One of Their nerds: "That's okay! Our web service uses SOAP. SOAP is platform and language independent and is great for interoperability. Oh, and our interface is so simple. I'm sure Ruby on Rails can talk SOAP?"

Me: "It sure can! Ruby on Rails prefers RESTful web services, but SOAP will work. This should be very easy, I'll be done by lunch. Hey! Talk to me a bit about the interface that allows us to update a FooBarWidget's data."

OoTN: "No problem. You call the FooBarWidgetUpdate() method and pass an instance of a .NET DataSet containing the data for the FooBarWidget."

Me: "Um, in what way is that platform independent?"

Awkward silence...

OoTN: "What do you mean? It's SOAP ain't it?"

Please, if you are going to tie your web service to .NET by using proprietary objects that shun the platform independence of SOAP, then please don't pretend that you are doing the rest of us any favours.