if soapResponse.getNewTagsSinceResult.respond_to? "tag"
if soapResponse.getNewTagsSinceResult.tag.is_a? Array
for tag in soapResponse.getNewTagsSinceResult.tag
@tag = Tag.find_by_sync_id(tag.id)
if (@tag)
@tag.name = tag.name
@tag.save
else
@tag = Tag.new
@tag.name = tag.name
@tag.sync_id = tag.id
@tag.save
end
end
else
tag = soapResponse.getNewTagsSinceResult.tag
@tag = Tag.find_by_sync_id(tag.id)
if (@tag)
@tag.name = tag.name
@tag.save
else
@tag = Tag.new
@tag.name = tag.name
@tag.sync_id = tag.id
@tag.save
end
end
end
That bit of code is really bugging me. It is ugly and unweildy.
SOAP:WSDLDriver in Ruby lets you call Web Services and generally it works well. In this case though my Web Service returns an array of Tag which seems to be tripping WSDLDriver up. You create your SOAP object, call the Web Service and then the results are stored in Tag off of the SOAP object.
If there are multiple items then Tag is an array. That is what I expected and it works fine.
However if there is just one item then instead of Tag being an array of one item it is an actual Tag instance. So you have to use different code to access it rather than an array.
It gets worse though. If no items are returned then there is no Tag member at all. The first line of code deals with that. It checks if the SOAP object “responds” to the Tag member. If it does then something was returned but we don’t know yet if it is an array or a single object. So we have to use is_a? Array for that.
With all of this we end up with two blocks of code that really should be one. I can refactor out the add/save/update bit but the nested ifs are ugly.
Ideally the Ruby library should return an array whether or not there are items. I can then simply do a length check on the array.
I may be wrong but this seems a poor design choice on the part of the SOAP:WSDLDriver coder rather than a slight on Ruby itself. Possibly the wonderfully dynamic nature of Ruby has tripped the coder up.
What I am really hoping for is someone to respond to this post and say “Use this line of code instead and you’ll have pretty code again.”