One of the most interesting talks I saw at railsconf this year was presented by Ryan Smith about the worker pattern. After seeing the talk, I thought about how the same pattern could be implemented using an evented framework and ended up building a proof-of-concept in node. Before we look at my implementation, let’s briefly review the worker pattern.
The Worker Pattern Overview
In a nutshell, the worker pattern is about breaking pages down into separate fragments that can be requested concurrently by the browser after the page loads. In a language like ruby, there are three main components to the solution: the client side code, the workers and a cache.
In the user’s browser, javascript is used to request the fragments after the page is loaded. The requests are made using a polling technique, continually calling the server until the fragment is ready to be serverd. All fragments are requested concurrently.
On the server, fragment requests are delegated to workers that run outside of the request/response lifecycle. Generating these fragments usually involves external api calls, long database requests or other timely operations. By removing these long operations from the request/response lifecycle we can avoid overloading our server with many slow requests.
Finally, the results of these long-running operations are cached to save time on subsequent requests.
The Workerless Pattern
Using a framework like node, we can implement the worker pattern with an interesting twist: workers outside of the request/response lifecycle are unnecessary. Why? Because node is evented. This means that operations with long running i/o can be executed in a non-blocking fashion. Although a request to an external api may take several seconds to return, this call will not stop our server from continuing to serve other requests.
Without the complication of background workers, our pattern becomes much easier to implement. Let’s look at each of the pieces in detail.
Client Side Code
The client side code is straighforward: make several concurrent requets to the server using javascript and populate the page with the results of these calls. A benifit of using node on the server is that we do not need to implement a polling strategy. Our server will simply hold the requests while building the fragement and return the contents when ready. Again, holding the requests does not block our server from continuing to serve requests.
The html just provides some empty divs into which the fragment content will be loaded. It also loads the clientside coffeescript.
<h1>Node Worker Patter</h1>
<div id="a">
<img src="/images/spinner.gif" />
</div>
<div id="b">
<img src="/images/spinner.gif" />
</div>
<div id="c">
<img src="/images/spinner.gif" />
</div>
<script type="text/coffeescript" src="/javascripts/client.coffee">
</script>
The client coffeescript is below.
makeRequest = (url, callback) ->
$.ajax
url: url
success: (data, status, request) ->
callback(data)
error: (request, status) ->
console.log(status)
$ ->
makeRequest '/fragment/a', (content) ->
$('#a').replaceWith(content)
makeRequest '/fragment/b', (content) ->
$('#b').replaceWith(content)
makeRequest '/fragment/c', (content) ->
$('#c').replaceWith(content)
We make an ajax request to the server for each fragment. After receiving the fragment respones from the server, we replace the divs on our page with the fragment’s contents.
Server Side Code
The server is written in node using the express framework. First, we’ll take a look at setting up the express app.
express = require "express"
externalApi = require "./externalApi"
app = module.exports = express.createServer()
app.configure ->
app.set "views", __dirname + "/../views"
app.set "view engine", "ejs"
app.use express.static __dirname + "/../public"
app.get "/", (req, res) ->
res.render "index", {}
app.get "/fragment/:fragmentName", (req, res) ->
query = req.params.fragmentName
externalApi.slowFind query, (err, result) ->
res.render "fragment",
fragmentId: result
fragmentContent: result
layout: false
app.listen 3000
console.log "Express server listening on port %d", app.address().port
Our express app sets up two simple routes.
The ‘/’ route serves the skeleton html shown in the last section. The ‘/fragment’ route makes a slow “external api” call and then renders the fragment view. Let’s look at that view now.
<div id="<%= fragmentId %>">
<p>Content -- <%= fragmentContent %></p>
</div>
In the previous section, we showed the client side code that was making the requests to our server’s ‘/fragment’ route. The simple div shown above will be the contents returned to those ajax requets and will, in turn, be displayed on the page.
Next, let’s take a closer look at what’s happening in our external api call.
cacher = require './cacher'
performSlowExternalCall = (query, callback) ->
timeout = Math.floor(Math.random() * 3001)
setTimeout ->
callback("result for #{query}")
, timeout
slowFind = (query, callback) ->
cacher.performCached
query: query
hit: (value) ->
callback null, value
miss: (cacheResultCallback) ->
performSlowExternalCall query, (result) ->
cacheResultCallback(result)
exports.slowFind = slowFind
Basically, we’re using a timeout to represent a slow external call. We first call the performCached method on the cacher object. If the query is not present in the cache, we call the performSlowExternalCall method which sleeps for a random number of seconds and then returns a result string. If the query is present in the cache, we simply return the value from the cache directly to our callback, avoiding the costly api call.
Caching
Finally, let’s take a quick look at how we’re caching the results of our “external api” calls to avoid duplication of effort. Here’s the cacher code:
EventEmitter = require('events').EventEmitter
redis = require "./redisClient"
client = redis.namespacedClient "worker"
class Cacher extends EventEmitter
constructor: (options) ->
@query = options.query
@on 'hit', options.hit
@on 'miss', options.miss
perform: ->
client.get @query, (err, result) =>
if result?
@emit 'hit', result
else
@emit 'miss', (result) =>
client.setWithExpiration @query, result, (err, setResult) =>
@emit 'hit', result
exports.Cacher = Cacher
exports.performCached = (options) ->
cacher = new Cacher options
cacher.perform()
The code here is a bit complicated and probably warrants a post of its own, but the general idea should be clear. When calling perform, we first check to see if our query exists in the cache. If it does, we simply emit the ‘hit’ event with the value, which calls user-defined hit function. If the query is not in the cache, we emit the ‘miss’ event, calling the user-defined miss function. We pass the miss function a callback that, when called, stores the result into the cache and then emits the ‘hit’ event with our result.
Wrap Up
The worker pattern is a clever way to speed up page loads and leverage the concurrency of client side javascript. In an evented framework, such as node, this pattern becomes more elegant by eliminating the workers altogether. If you’d like to check out the complete proof-of-concept I threw together, you can find the code here.
Drew
In the past couple of weeks I’ve discussed ruby’s #enum_for method with a few people, so I thought it would be a good idea to write up a description of what the method is and how it works.
To motivate the discussion, let’s consider a simple problem - given an array, we want to return a new array that contains the sum of each pair of elements in the original array. We’ll call our method #pair_sums. Here’s how the method should work:
[1, 2, 3, 4].pair_sums
# => [3, 7]
[1, 2, 3, 4, 5, 6].pair_sums
# => [3, 7, 11]
A Simple Solution
Below is a first pass solution to this problem. For simplicity, I’m assuming the array contains only integers and has an even number of elements.
class Array
def pair_sums
pair_sums = []
self.each_slice(2) do |a, b|
pair_sums << a + b
end
pair_sums
end
end
The code above is alright, but it’s annoying that we have to create a new array in a local variable. It would be much nicer if we could combine #each_pair with #map to build up a new array of the sums without having to create a local variable.
A Better Solution
Now let’s use #enum_for to get rid of that pesky local variable from the previous example.
class Array
def pair_sums
self.enum_for(:each_slice, 2).map do |a, b|
a + b
end
end
end
So what the heck is going on here? What is the #enum_for method doing? In a nutshell, it’s creating an instance of the Enumerator class and returning it. The Enumerator instance returned includes the Enumerable module and defines the #each method. The trick is that the Enumerator’s #each method is defined as calling #each_slice on our array with the argument 2.
I know, I know, it’s confusing. To help, let’s implement our own #my_enum_for method and MyEnumerator class.
Our Implementation
First, let’s define #my_enum_for on Array. It will take a method and some number of arguments and will return an instance of MyEnumerator.
class Array
def my_enum_for(method, *args)
MyEnumerator.new(self, method, *args)
end
end
Note that we instantiate MyEnumerator with the instance of Array on which we called #my_enum_for. We also pass along the method and arguments.
Next, we’ll have a look at the implementation of MyEnumerator. Take a second to read it over and then read the detailed description below.
class MyEnumerator
include Enumerable
def initialize(object, method, *args)
@object, @method, @args = object, method, args
end
def each
@object.send(@method, *@args) do |*block_args|
yield(*block_args)
end
end
end
The first thing we do in our MyEnumerator class is mix in the Enumerable module. When a class mixes in the Enumerable module, it agrees to a contract — the class must implement the #each method. If this contract is met, the Enumerable module provides a large number of enumeration methods (such as #map, #select, #inject, etc.) for free based on the implementation of #each.
In the #initialize method, we simply store the object, method and arguments in instance variables. We’ll use these in our #each method.
Finally, let’s look at the implementation of #each. Using the instance variables we stored in #initialize, we call the given method on our object with the provided arguments. It is expected that the given method also take a block. We then yield the block’s arguments. This means that we are defining #each on our MyEnumerator instance to call the specified method on the object we passed in. In our #pair_sums example, the MyEnumerator instance will call #each_slice with the argument of 2 on our array. Then, for each slice of two items, it will yield the values. Therefore, the behavior of #each mimics the behavior of #each_slice. Because the behavior of #map is dependent on the implementation of #each, we can now #map across each set of two items and sum them up.
With the above definitions, we can redefine #pair_sums using the method we created.
class Array
def pair_sums
self.my_enum_for(:each_slice, 2).map do |a, b|
a + b
end
end
end
An Even Better Solution
We can make things even nicer. In ruby 1.8.7 and later, many Enumerable methods called without a block will instead return an Enumerator instance wrapping the called method. You can imagine #each_slice to be defined as follows:
def each_slice(*args)
if block_given?
# implementation goes here ...
else
Enumerator.new(self, :each_slice, *args)
end
end
We can take advantage of this feature to implement #pair_sums in an even more concise manner.
class Array
def pair_sums
self.each_slice(2).map do |a, b|
a + b
end
end
end
Some Final Notes
Just a few quick notes for wrap-up:
- This is not the actual implementation of Enumerator. However, I find it helpful to think of the behavior this way.
- The Enumerator class has another instantiation form in which a block is passed to the #new method. It allows the Enumerator to be used similar to a python generator. That behavior is beyond the scope of this post.
Drew
I hate unnecessary merge commits. That is, I hate navigating a git tree of commits littered with merge commits. It is like eating a cupcake in which a small amount of sand was accidentally mixed into the batter. It may still be edible but no one is going to enjoy eating such a thing. Inadvertent mistakes like these may seem minor at first, but eventually one finds her focus drawn to the mistakes rather than the content.
Merge commits are necessary in some cases, such as merging two divergent branches. When one finds himself new to the ideas of git and coming from a system such as SVN, it can be difficult to grok the horrors he wreaks on his fellow developers by not understanding the differences between SVN and git.

The good news is that unnecessary merge commits are easy to avoid once we embrace rebasing. Let’s play through a scenario and see how we can improve our approach. If you don’t understand what we’re doing here just remember Tony Harrison and his incredulity toward unnecessary merge commits.
git commit -m 'lalala so care free using git'
git push origin master
=>NOT UP TO DATE
git pull
=>MERGE MADE BY RECURSIVE
git push origin master
Git is decidedly not SVN. This kind of workflow leads to overly complex git trees (even though they may look pretty in GitX) and smells of a misunderstanding about the tools we’ve chosen. Next time, instead of refusing to understand why git is different from SVN, we can try the following:
git commit -m 'lalala so care free using git'
git push
=>NOT UP TO DATE
git pull
=>MERGE MADE BY RECURSIVE
git reset --hard <SHA of your last commit>
git rebase origin/master
git push origin master
Now that is an awful lot of work requiring us to find the SHA hash of our original commit or use special git notation for denoting parents of a commit. Seems like we could avoid that simply by pulling down the latest changes before we commit.
git pull
git commit -m 'lalala so care free using git'
git push
But this kind of technique is only useful when we are planning on pushing changes out immediately. This workflow actually tends to treat git more like SVN than the first one. Most of the time, I would not recommend the above workflow, but it will avoid merge commits. However, I think we can still do better thanks to a git configuration tip from @kEND.
git config branch.<branch>.rebase true
Whenever we pull changes down then our commits will automatically be rebased on top of those changes rather than merged together. Our workflow will end up looking like the first one, which is much more intuitive (commit*n => pull => push). The technique of automatic rebasing leaves less room for error in trying to remember all the steps and guidelines above.
git commit -m 'lalala so care free using git'
git commit -m 'another awesome commit'
git commit -m 'more awesome to share with the world'
git pull
=>Rebasing your changes on top of the remote branch...
git push origin master
From my limited understanding of git, I would prefer it to work this way by default, but I am guessing there are reasons why this is not the case. What kind of git workflow tricks do you use?
Adam
If hypermedia is meant to be the engine of application state (HATEOAS) and we can think of that engine being driven by a browser then what role does Javascript play? Javascript (in the browser) should depend upon hypermedia to provide a richer user experience. However, hypermedia and Javascript should not be co-dependent.
Javascript is not hypermedia. A resource’s representation should contain information describing possible states. A user’s ability to choose her next state should not depend on Javascript to facilitate that change. Javascript should be used to enhance these state changes rather than define them.
Ridiculous Car Analogy

Tightly coupling a web application to Javascript would be like a car manufacturer installing a giant LCD screen in place of a windshield. This “video windshield” may provide a better driving experience, but if it fails or is buggy then that could seriously limit the driver’s ability to use the car. Someday manufacturers may choose to add such a device to cars. If that day ever comes I imagine it will function first as a windshield and second as a HUD. And the former is not likely to be dependent upon the latter. Of course, one could always assume that users are okay with (or even prefer!) driving around like Ace Ventura. The fact is, the “video windshield” has nothing to do with driving just as Javascript has nothing to do with the web. A rich user experience through client-side scripting has to do with the client (read: browser).
I imagine I could be lectured on the finer points of how this analogy falls apart, but if you would like to further discuss the minutia of analogies then I would like to introduce you to the keyboard shortcut (cmd|ctrl)+w.
The User’s Hierarchy of Needs
Understanding the importance of decoupling highlights why Progressive Enhancement is so important to creating a quality user experience on the web. Progressive Enhancement is not only a recipe for accessibility it is also a natural driver of Minimum Viable Products. By relying on standards to create the user experience it is possible to provide a baseline of functionality. There is a hierarchy of needs involved in any user interaction:

The goal should be delighting users, and that goal is reached by correctly addressing their needs. Users will inevitably disprove assumptions, and adapting quickly to new knowledge about users’ expectations is easier in loosely coupled systems. Most users will value a working system over a beautiful, broken system. The lesson is:
- Build the simplest, working system.
- Then make it efficient.
- Then make it a pleasure to use.
I want to clarify, however, that these steps are iterative and should be refined as more knowledge is gained. The real challenge in product development is finding the line where these separate. Fortunately, in the case of web development we have Progressive Enhancement to give us some simple guidelines. HTML is the engine. Stylesheets put things in the right place. Javascript provides a more engaging experience. If functionality can only be had with all of the above then there will be very serious issues for the user and the developer..
The Future of Javascript as Hypermedia (or How I Learned to Separate Concerns and Love the JSON)
I’ve shown that separation of concern in web development is important, but what does that have to do with Javascript not being hypermedia? I believe that Douglas Crockford is right when he says Javascript is a misunderstood language. In order to facilitate an understanding of what Javascript (read: ECMAScript) is it is firstly important that web developers see Javascript as separate from the web. Once it is understood separately it is easier to see that Javascript can be many different things—even hypermedia. Specifically, JSON has shown some promise toward becoming a form of hypermedia but it lacks standards. I think that is a hurdle JSON can overcome as people rally around it. It is much easier to parse than XML both technically and visually (see Mike Amundsen’s post on JSON hypermedia for an example of what this could look like).
I look forward to the day when more people recognize the ubiquity of Javascript. It is already being used for map-reduce functions in non-relational databases, REST-like APIs, writing highly concurrent servers, and building rich, interactive client-side applications powered by hypermedia. Javascript has a bright future; something many would’ve said was unlikely ten years ago. And I, for one, welcome our new functional, dynamically-typed language overlords brethren.
Adam
I’ve recently been working more with Javascript outside of the browser, thanks mostly to node.js. To jump in and learn the language, I tried to emulate some of the metaprogramming I’d learned from working with ruby. I’m going to show examples in ruby and the equivalent code in Javascript. Let’s start by setting up some ninja objects.
This is all pretty self-explanatory. We’re using node.js to require the puts statement in Javascript.
Now that we have our objects, let’s reopen our class/prototype and add some new behavior. This was one of the first things I found interesting (and later dangerous (and later interesting again)) about ruby. Turns out this is a piece of cake in JS as well.
In ruby we reopen the class simply using the class keyword. In Javascript we grab the prototype for our object and just attach a new function.
Next up we’ll add some behavior to specific instances. We want to add a method for throwing stars only to the drew instance, not the adam instance. Here’s the code.
In ruby, we add a method to the drew object using def {instance_name}.{method_name}. In Javascript the code is almost identical to the code that adds methods to the prototype. We just attach a function directly to the instance rather than the prototype.
The next thing we’ll look at is calling methods dynamically. The ability to call a method with a name given to us at runtime is a powerful tool in DSL creation and metaprogramming. Here’s the code.
This is very trivial in both languages. Ruby allows us to call methods based on strings or symbols using the send method, whereas JS allows us to use the square bracket syntax to access members of objects with strings. We then tack on the parentheses to call the method which we’ve retrieved from the object.
Now, let’s get into a meatier topic: defining methods dynamically with closures. What we want is the ability to define a method dynamically (given a name) that is also a closure over the lexical scope at the point of method definition. This means we will have access to variables, methods, and classes that are available at the time of the method defintion. Read the code below and then I’ll describe what’s happening here.
Let’s look at the ruby code first. You may notice that we’re using send to call define_method. This is a trick (hack) in ruby that allows us to call private methods without self being the implicit receiver. define_method takes a name for the new method and a block which describes the body of the method. In ruby, this block is a closure which means we have access to the scope at the time of the method definition. In the code example above, we take advantage of having access to the scope by returning the color defined outside of the method. This would be impossible if our block was not a closure because there is no guarantee that we would have access to this variable at the time of the method call.
The most interesting thing about the Javascript example is that it is exactly the same as the example of adding a dynamic method to a class. There is no difference because Javascript functions are closures. This means we get the ability to capture the scope at the time of definition for free. The ubiquity of closures in Javascript is extremely powerful and, as we have seen so far, makes metaprogramming very easy.
Let’s end with one final example: defining a method dynamically on an instance that closes over local scope and accesses the instance’s state. Code first, description second.
We’ll talk about the ruby example first because it needs more explanation. You can see the first thing we do is reopen the Object class to define a method called metaclass. This method retrieves an object’s metaclass (or ghostclass (or eigenclass (or whatever))). You can think of a metaclass as a class definition specific to a single instance of a class. This means we can add methods to an object’s metaclass without adding the same behavior to all instances of that object’s class. So we grab our ninja’s metaclass and then define a method using define_method, identical to the previous example of define a method on the class. One interesting thing to note is that we are calling the name method in the body of our define_method block. This is to show that our method has access to the instance’s state.
To be honest, there’s not much to say about the Javascript example because it is so simple. We avoid the whole metaclass business because Javascript uses prototypal inheritance. This means that Javascript does not distinguish between classes/prototypes and instances and, therefore, we can add our desired behavior directly to the instance. We use the exact same technique for adding a method to the prototype, but this time we simply add the function directly to the instance. Again, this function is a closure. And again, this function has access to the instance’s state using this.
Thanks to this exercise, we’ve learned that Javascript has tremendous metaprogramming facilities. As Douglas Crockford said,
…JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java.
Closures are so ingrained in the language’s design that metaprogramming seems to happen without even trying. This little exercise has left me very excited about the potential of Javascript not only as a great language for the web, but also as a powerful server-side language. You should be excited too.
Drew
In part one we discussed a simple way to create an unobtrusive login lightbox. In this post we’ll go over how to turn that simple code into something more useful by prompting users for credentials if they attempt to click a link that only logged in users can see.
Here is what we’ll be doing this time:
- Setup
require_user to deal with AJAX requests
- Setup jQuery AJAX handler for
401 Unauthorized errors
- Setup callback handler for attempted clicks
- Talk about Unicorns
Boilerplate
As in the previous post I’ve provided a git repository to jumpstart the example. If you are starting from scratch you can perform the following steps:
If you followed along with the previous post then you just need to pull down the latest changes and checkout the part_two branch. Also make sure to create a user using the Register page.
Returning the right codes
After we’re up and running we can see that clicking on the ‘Secret’ link does something unexpected.

Clicking this link should show us the secret message, but not until we’ve setup Rails to give AJAX requests special treatment. Adding support for this on the Rails end is simple thanks to authlogic.
So now we have our application server returning back meaningful HTTP Status Codes that can give our Javascript some direction.
Handling the codes
In the previous example we rendered the Login form in a lightbox any time a user clicked the Log In link. We also handled bad form data with the 406 Not Acceptable status code. This time we’ll take a less generalized approach. (note: The previous example’s Javascript has been refactored to make it easier to extend so make sure you’ve pulled down the latest changes and are working off of the part_two branch.) We need to call MyApp.renderLoginForm anytime an AJAX request returns a 401 Unauthorized response. The following snippet demonstrates what we need to do:
And now when we click the Secret link we get a more reasonable looking result.

In the previous example we were performing error handling using the error property set in ajaxifyLoginForm. We’ve simplified error handling on AJAX requests by hooking into jQuery’s ajaxError method.
Establishing a Callback Mechanism
So now when we login after clicking the Secret link we’re taken to the Account Page.

Well that’s not exactly what we wanted… What any user would expect is to be shown the Secret data after authenticating successfully. One way to solve this problem is to keep track of links the user clicks that result in errors. We can put the clicked link into a variable to be automatically re-clicked upon successful authentication. By doing this we have made a decision to let the user maintain their own conversational state.
With jQuery we can hook into the error property of AJAX requests once again and store the attempted link in a Javascript variable
After we have this variable we can change our success callback to click the variable.
AWESOME

If you’ve run into any problems along the way please refer to the part_two_solution branch.
“But why doesn’t it create Unicorns for me?”
- HTTP alongside HTTPS is not supported with AJAXy login mechanisms due to the Same Origin Policy. I have done it with iframes and it is not worth it in my experience. If security is important to your users then you should show a full HTTPS page so that the user has confidence that his or her data is secure.
- The Javascript application can be refactored even further. See the
part_two_refactored branch for my approach.
- Now that a user can log in and stay on the same page we should look at replacing “Register | Log In” with the links which a logged in user would see.
- Adding support for forms which require a logged in user follows the same principle. You can see an example in the
part_two_refactored branch.
Adam
In my previous post I hinted at how an unobtrusive javascript login system might look. I’ve put together the following example to expand on the idea.
Here are the steps that we’ll cover:
- Create a working HTML-based login system
- Enhance the login links to show the login form in a lightbox
- Add error handling to lightbox login form
- Discuss some of the problems with a completely unobtrusive approach
I’ll be using the authlogic gem for authentication, jQuery for awesomeness, and facebox for a lightbox.
Simple HTML login
Rather than building an authentication system from scratch I’ve forked Ben Johnson’s authogic_example.
At this point we have a working app that will let us register and login along with all the javascript libraries we’ll need.
Enhancement
First, we need to change the UserSessions#new
What is happening here is that we’re choosing not to render the layout if the request is an AJAX request.
The next step is to add an identifying attribute to the login link to create a lightbox. We’ll go ahead and follow the Facebox idiom of adding rel="facebox":
Now we can move to the Javascript.
Facebox makes this super simple. However, in the next part we’ll have to take more granular control of displaying the lightbox in order to deal with AJAX-ifying the login form.
Behold!

Error handling
Now we have an awesome lightbox but when we submit bad data then the page changes and we end up at the regular old Login page. We need to add the appropriate javascript and change the create action to handle bad stuff.
The final step is to call the function we just defined in the success callback so we always attach this behavior when the form is loaded.
This might look complex but here is what is happening:
- We attach to the click event for the login link.
- We pass
facebox an anonymous function so that we will still see the loading animation immediately after the user clicks the link.
- We do a
GET on the link’s href, open that in the lightbox, and AJAX-ify the newly added login form.
Now when we try to login with bad credentials…

If you’d like to see all of this put together then you can checkout the part_one branch (git checkout -b part_one origin/part_one).
Problems
I am not preaching the One True Way™, rather, I am trying to find a better way. Here’s some disclosure about the problems I see with this approach:
- We have to put a fair amount of HTML in our Javascript. Instead, the controller could render the action minus the layout with a status of
406.
406 Not Acceptable may be a bad choice for bad params. I really don’t know which code is the best choice.
- If we go to
/user_sessions/new and click the login link then we render the login form twice on a page which means there are two DOM IDs of #new_user_session
- We’ve put
request.xhr? in the controllers and added more complexity. We could take a more idiomatic approach using something like format.xhr or respond_to_xhr by building a Rails plugin.
Next steps
In part two we’ll go over how to prompt a user with the lightbox for credentials when she clicks a link requiring an authenticated session.

Adam
When people think about AJAX in the Rails community they might think of something like:
Where this is meant to use format.js to take care of the ajaxy stuff. However, I believe this is incorrect and stems from a misunderstanding of what Javascript does. This is not a shortcoming of the knowledge of the Rails community. Javascript has had a troubled life. It wasn’t until libraries like Prototype.js came along and started to show web developers the good parts of Javascript that I really started to see things change. And then it wasn’t until Progressive Enhancement and Unobtrusive Javascript came along that we started to treat Javascript like a first-class citizen.
If you were playing with the web stack (HTML/CSS/JS) ten years ago then you know that Javascript boiled down to a lot of horribly obtrusive one-liners that fit into onclick attributes in links. We’re past that. I think that as developers living on the edge of the second decade of the 21st century we should be able to say “We are past that.” We have libraries like jQuery. We have highly concurrent servers like node.js. We have an understanding of Javascript functionally rather than procedurally.
Getting Past That
Oftentimes the format.js will contain something like this:
This is not okay. I admit I have code doing this right now. I do not like it, and I am actively seeking out ways to kill it. Writing something like this means that when I eventually build an API for my resources (and I will have to if I believe the year is 2009) that a Javascript representation will make the following assumptions about the requester:
- it has jQuery
- it will
eval the response
- it has a DOM element with the ID
some_id_in_the_layout that should be shown
An application ought to return data, not code[needs citation :P]. The javascript conventions provided by Rails hardly embrace this idea with things like RJS. But I will readily admit that I often don’t know how to solve certain problems without having an action return data and code. One way that I’ve started to approach this problem is by letting my javascript do things based on HTTP status codes. I’m not too sure about these ideas but I imagine sharing them engenders solutions. Doing what I was doing ten years ago engenders ignorance.
Let’s say you want an action to return real data on a AJAXy GET.
Why is this approach better?
- It is all Ruby. There is no javascript in a
render :update block. And there are no RJS idioms tightly coupled to Prototype.js
- It will honor the HTTP Request’s Accept Header but only render that resource, not an entire page.
- It makes it difficult to make unnecessary exceptions about a resource. Each resource should have a set of representations (i.e., formats). I honestly don’t know what the Javascript representation of a Post resource would be, but I think it might have something to do with embedding (e.g., Embedding a gist) rather than out-of-context manipulation.
So what about the HTTP Status Codes? One place I’m currently using this approach is with an unobtrusive login system. The require_login filter might look something like this:
Now in javascript(with jQuery) an attempt to perform an action that requires a login can behave appropriately:
So the idea here is that when any AJAX request receives an HTTP Error Code it can act appropriately without the server needing to return javascript which is tightly coupled to the application server. This can apply to success codes as well with the ajaxSuccess hook in jQuery. I’m still trying to figure out which codes go where and in which circumstances they ought to be returned. My theory is that the 406 Not Acceptable could be used when a validation fails while attempting to create or update a resource. If you have any ideas what the right idioms might be please leave a comment or contact me @scudco.
In the end this is all an evolutionary process. Most advances in understanding do not come from “You have been doing it wrong.” Instead, they come from phrases like “Maybe I am doing it wrong?” or “Maybe I can do this differently.” And that is exactly how I feel about RJS. Something rubs me the wrong way and I know it can be done differently. For me, RJS was a great stepping stone toward a deeper respect for javascript.
Adam
The Gordian Knot
Recently I’ve been exploring the concept of progressive enhancement. I won’t rehash the idea here, but I will restate the approach so it fits my Test-Driven brain.
- Write just enough markup to display all the necessary content of a resource.
- Write just enough styles to turn your markup into something nice looking.
- Write just enough client-side scripts to make your content interactive.
Admittedly this isn’t the stated goal of Progressive Enhancement, but it is the way I’ve applied it to my work practically. The reason for this is Separation of Concern. Your markup is markup. It should communicate context and be semantic. It is tempting to think that all my problems are Gordian knots that can only be solved through forcing a solution and disregarding the wisdom of my elders. But the web is about sharing… or agreement… or something. So maybe I’m not sure what the web is exactly, but I can say with confidence that it isn’t about spamming as much code as you can write until something works. If I’m building web applications and insist on the Alexandrian sword of the limits of my own knowledge then I am willingly embracing obsolescence.
The End of Language Superiority
The world thrives on diversity and so does the web. It is empowered by diverse technologies working together, and it is much greater than the sum of its parts. Separation of concern is similar to separation of labor. When I can solve a very large problem by breaking it into smaller problems then it is much easier to change my solution as the problem inevitably changes. This also allows an expert in CSS to solve the problem of styling my content. In addition, building web applications out of a variety of technologies and having a sympathy for each of them is a good thing. The age of language superiority is over.
The Aggressive Curmudgeon
Now to deal with the curmudgeonly developers who reject diversity and sympathy in favor of depth of knowledge. They insist these new ideas are idealistic and ultimately unfruitful. This leads them down the road of forceful swings from their favorite tool which begin to lay foundation for the Great Rewrite of 2011. Software written by the aggressiveness of willful ignorance is not meant to be shared.
If the web is about sharing and the web is represented through code then every piece of code one writes is for someone else. It might be said that in the age of non-distributed computing that developers should own their code. To put it another way, “your code, your problem.” But just as the age of language superiority is over so the age of individual code ownership is over. However, let me be clear that I am not saying “your code, our problem.” That is simply not the way the open-source community works. If one writes poor code then he suffers the consequences of no one using or contributing. Unfortunately, the latter paraphrasing rings true in most businesses because a developer inevitably moves on and new developers must work together to produce something. That is, developers are paid to accept the idea that someone else’s code is their problem.
The Impracticality of Perfection and the Reality of Improvement
When I code I do not strive for perfection. Instead, I attempt to improve my skills by learning from others who know more than me. When a mentor is unavailable (often this is the case) I attempt to approach a problem in a different way. Where I might have used an abstraction to solve a problem I did not understand in the past I attempt a more advanced methodology. The great news is that, though mentors may not be available, there is a wealth of information from people much smarter than myself. Again the web is about sharing. When solving a problem one ought not relegate himself to learning nothing new. Perfection is for Guitar Hero. Improvement is for software craftsmen(and women!).
The Hard Facts
Anecdotes and flowery language interpreted by multiple readers is bound to miss the mark at which I’m aiming so allow me to be a little more objective in my conclusion:
- Your problems are not intractable.
- There are people in the world who speak different languages. Learn them.
- The web is about sharing.
- Write code for your successors.
- Improve your skills by holding yourself to higher standards than you might comprehend.
Adam
Testing your views is often the brunt of many jokes in the Ruby community. The importance of view testing is starting to make a come back with things like Cucumber and Webrat, but I’ve been thinking more and more that testing your views is about content. We’ve recently started a redesign at my current job and I decided I would attempt to achieve view zen by writing absolutely no code until my specs told me to do so.
I wrote some view specs to assert what content should be shown on a particular template and made them pass. Pretty easy stuff. Here’s an example:
Done and done.
After writing a number of similar looking specs for other pieces of information on a Business I was not sold on their usefulness. It seemed like I was traveling down a testing path that was useful to give me direction, but not necessarily flattening the cost of change in the future.
But wait, why do I even care that there is a <span> tag with the business’s name it? The truth is that I don’t and neither do any of the stakeholders. The stakeholders care that the view looks correct and displays the content correctly. View specs like these aren’t valuable to anyone but developers. They don’t actually describe anything about this content. I started to wonder if I was actually making my successors’ jobs harder by writing such rigid specs. I decided I would continue to write view specs but with an intention of describing the content being displayed. The next set of specs I wrote looked a little more useful. I’ll modify the previous example to demonstrate what I’m saying
Great! Now this spec actually attempts to say the markup should attempt to describe its content. I was feeling much better about this approach and happily adding ids, classes, and markup meant for the content. I felt like I actually understood why I should not write HTML for a browser, but rather to markup my content.
Once I had finished the specs for the views a new story came along asking to implement the hReview-aggregate microformat. This meant that I was actually supposed to be testing specific classes and tags on the content. Here’s an example:
After finishing that up and discussing the approach with @nolman and @drewolson I came to the conclusion that view specs are great if you need to describe your content. However, even if a stakeholder is not asking for microformats they are a great way to structure content.
In the future I’d like to try writing my view specs with microformats in mind first. If you’re having trouble understanding why this is actually easier than ad-hoc view testing then I would recommend you read an http://errtheblog.com/posts/53-microformathingies He talks about removing Chowhound’s API in favor of semantic markup in HTML. I don’t necessarily think a REST API (via JSON or XML) and semantic markup should be mutually exclusive, but the idea that you can test your markup through parsable microformats means you can have more confidence that your content is meaningful to your customers and consumable by machines.
I might want to say something like this rather than testing view specs using have_tag and with_tag.
You get the idea. I think this may be possible with Mofo and some custom rspec matchers.
Resources on view specs:
Resources on microformats:
Adam