Saturday, January 16, 2010

Rails: The REST Religion

I like Rails. I like Web services. I even like making a strong distinction between GET and POST for all the standard reasons. However, I do not like the REST religion.

It's a simple fact of life that Web browsers don't currently support DELETE and PUT. Rails compensates for this by passing a parameter _method=DELETE. The REST religion contends that REST is simple because it cooperates with how the Web is supposed to work. However, the Web as most people use it is browser-based, and my current browser doesn't support DELETE and PUT. In fact, I'm going to have to deal with browsers that don't support DELETE and PUT for many years to come. Hence, Rails' use of _method=DELETE is a HACK in order to try to force the Web to be something it isn't, all the while claiming that RESTful routing is the way the Web is meant to work.

Nowhere is this more evident than in this code:
<%= link_to "Delete", project_path(@project), :method => :delete %>
That little helper generates a link that when clicked on, creates a form on the fly (using DOM methods) and then submits the form. The form has a hidden field with _method=DELETE. If you have JavaScript turned off, it'll end up loading the wrong action--show instead of destroy.

This is a well-known problem which they're hoping to address in the future. By the way, did I mention that this is used whenever you generate scaffolding? Here's my point: in an effort to make the Web behave in a way that we all wish it did, they overlooked the way in which the Web actually works. In the real world, you can't count on the user having JavaScript. In fact, my boss submitted a bug against me because he had JavaScript turned off, and clicking a link lead to some mysterious behavior because it executed the wrong action.

As I mentioned Rails has a thing called RESTful routing. It's a routing system in which the URL as well as the HTTP method determine which action gets called. I don't know why, but for some reason I have a standards body that lives inside my head, and they won't tolerate me using anything other than RESTful routing. Even though I've read "RESTful Web Services" cover-to-cover, and I've read the section on RESTful routing in the Rails book, I must admit that RESTful routing actually causes me far more pain than any other feature of Rails. I use things like nested routing, special :member actions, special :collection actions, etc. However, unless I'm doing an admin GUI, I always feel like I'm trying to shove a round peg in a square hole.

I wish I could just stick with GET and POST. I wish I could abandon the idea of Resource Oriented Architectures which insist that you may use any noun you want, as long as you only use the verbs GET, POST, PUT, DELETE, HEAD, and OPTIONS. I wish I could use any beautiful verb I wanted to and shove it in the URL all willy-nilly. I wish I could just go back to the old days of :controller, :action, and :id without people thinking I'm stuck in the stone age. I wish I could group my controllers and actions based on how the user interacts with the page instead of trying to separate everything neatly with one resource per controller.

Last of all, I wish I were more pragmatic, and that I didn't have a standards body living in my head telling me what to do all the time ;)

Friday, January 01, 2010

Ruby: Strings

Doh! I forgot Ruby has mutable strings. I expected "s << something" to be the same as Python's "s += something". However, in Ruby "<<" actually modifies the string. That's really bad if there are any objects that have a pointer to the same string and aren't expecting it to be modified.

(I'm not criticizing Ruby. I just wasn't expecting it. I would never make that same mistake with something I knew was modifiable, like a hash.)