tags:

views:

95

answers:

2

Hello everyone, I am doing a one-way data transfer app from MS Access to a Rails app. I keep the Rails app restful, so I tell my colleague that the Access app needs to keep track of whether or not a record is already sent over to the Rails app because the Access app will need the ID of that record in the Rails app to do "update". He doubted it was necessary as, if, for example, Access sends a record to the Rails Person model with the Access app's person model ID, let's call it AID, so if the Rails app "sees" incoming ":name => 'John Doe', :aid => 123", and finds no such Person model with 'AID' equal to 123, then Rails should just create it, and when it does find a Person model with 'AID' equal to 123, then update it.

I told him that the design is restful and it is a 'good thing' to keep two separate calls (one with post and one with put); the one with 'put' needs the ID of the record which the call is about to update.

But he has some good point, why do we differentiate create and update but not merge it in one method in which a check of whether or not the record is already there can determine if it'll be a creation or an update?

Thank You!

+1  A: 

I agree with your colleague. Ultimately services should be easy to use and do the hard work for the caller. Forcing the caller to remember whether a create or update is needed is annoying.

As i see it in order for him to know whether to call Create or Update would mean he would need to either

  1. keep track whether he called Create already (which means you can't remove the record in the Rails app without telling him)
  2. he needs to ask the Rails app whether the data is already in the system, and then call the right API.

Both options suck.

One other thing to add. That doesn't mean your service has to always first check if the record already exists. If expect your usage to be skewed heavily for one operation (ie updates happen often but insert are seldom), then it probably makes sense to "assume the record is there and do an Update, if it fails b/c the record isn't there, then do an Insert".

mlathe
Thank you for your reply Mlathe. I think there are on average as many creates as there are updates. But that's proportion, when I look at the numbers, I think we're talking about something like when a record is created (so 1 for create), it usually gets updated about once in its "useful life cycle" (ie, before it is billed ;) (so 1 for update,too; hence the 50/50)I thought about having Access ALWAYS send a create first then a update, and use validate_uniqueness_of :AID to fend off excess creates so to fail the create and proceed with the update that follows. It sounds so hackish, though.
Nik
yea, it's not great, but building that logic in your service decouples the two systems. As a result you can make changes to your data without fearing that you might break the Access App. Another way to look at it is if the access app needs to remember that it sent the info already, then it's like you are making a copy of your data in the Access DB (ie it is important to keep them in sync). As you might guess replicating data across several DB's is a real pain and a bad practice.
mlathe
Thanks again for your insight. It's valuable for me to know that my hunch about keeping Access App basically untouched by doing all the dirty work over at Rails instead was a good guidance in making decisions like this.
Nik
A: 

While in many cases you might not need to care about the difference, Create and Update are fundamentally different concepts.

There are many cases it would be fatal to blindly update (and thus overwrite) a record, when a Create would have failed because a duplicate id was found.

If that is not the case with your app, and never will be in the future, I'd say it might actually be fine to merge create and update - or perhaps keep the create and update mehods but provide a 3. api which does does both.

leeeroy
Thank You for helping out here Leeeroy. As a matter of fact, I created for each controller three separate "access_create, access_update, and access_destroy"s just for this data transfer phase of the project. Just so that I thought when the time comes, I can just "unplug" the whole Access bridge thing without consequences. But I guess it is OKAY, then, to have a 'fused' method that checks for existence then either create or update. I hope to get one silly thing straight: RESTful rails controller doens't mean there can only be 7 actions, right?
Nik