Master Sword
<%= 'Cause it's late and your momma don't know %>

Has Anybody Seen My Code?

The Ruby Rogues posted their Jim Weirich Tribute Episode on April 9th, 2014, a little over a month and a half having passed since Jim’s passing. Having first started practicing Ruby around a year ago, I admit that — while I certainly appreciated Rake — I hadn’t spent the time to get to know (from a distance, at least) the wonderful man behind the code.

Now, having fallen asleep many a night to a Jim Weirich conference talk, having perused the 100-line Ruby program that became Rake, and having read and/or listened to the anecdotes of Jim’s peers, it is clear to me that Jim Weirich was the friend, mentor, and creative innovator that any forward-thinking community needs. The anecdotes, in particular, have reminded me that the challenging of conventional thought is often the source of innovation. Moreover, the time we give to others is as valuable as the time we keep for ourselves.

At the crossroads of these two ideas stood Jim Weirich, a man who believed in his own opinions and gave others’ their time of day. We all can learn a lot from Jim the programmer and Jim the person. I know I have.

Loathe Doing Laundry? Scamper Whilst.

For me, doing laundry is generally one of those monotonous tasks that can bring an otherwise lively day to its knees. Be it the setting of a damp, unfinished basement; the jarring sound of the drier buzzer; or perhaps the infrequency with which I’ve had to attend to this necessary matter over the years, there is something about laundry that dims my mood. In fact, I’ve come to realize that laundry extracts from me and reveals of me a childish attitude – one not of glee, but of sluggish submission.

I’m not sure that I ever made a conscious decision to stop loathing laundry, but I do know that I learned to make it more enjoyable. How? Childish enthusiasm, of course.

One day, rather than slogging through the process, I decided to run – er, scamper, more appropriately. From the washer to the drier. From the drier to the washer. To and fro. Back and forth. Up and down the stairs (with tact, no doubt). Arms full of wet clothes and momentum on my side, I launched freshly plucked t-shirts and gold-toed socks through the dry basement air. My feet were nimble, my spirit alive. Surmounting my basement staircase, I wore a wry smile. I had conquered monotony.

I haven’t stopped doing laundry this way. I do my best to fly like the wind (Bullseye). Approach — in any walk of life — can make quite the difference.

Customize Named Model Attributes with ActiveModel::Serializers

If you’ve used ActiveModel::Serializers to serialize your Ruby objects into JSON (presumably in a Rails application), you’re familiar with the tools that Yehuda Katz’ brainchild affords us. When using Rails to build JSON APIs for front-end JavaScript applications (or general consumption), we can rely on ActiveModel::Serializers for serializing not only database-backed model attributes, but also custom attributes and associated records.

class GiraffeSerializer < ActiveModel::Serializer
  attributes :name, :age, :name_and_age, :height, :children

  def name_and_age
    "#{name} - #{age} year(s) old"
  end
end

In most applications, these features will suffice. However, when working on an AngularJS front-end recently, we sought to serialize a boolean model attribute as a string. The “why” is somewhat irrelevant, but it had something to do with a quirk in binding model attributes to form inputs in a directive. In any case, the task seemed simple. Perhaps something like the following would work.

class UserSerializer < ActiveModel::Serializer
  attributes :boolean_attribute

  def boolean_attribute
    boolean_attribute.to_s
  end
end

As you can probably see already, this isn’t a solution. The nasty feeling we permit when writing this code is accompanied by an ugly stack trace error. Onto the next one.

Luckily, “the next one” just so happens to be an ideal solution. If you seek to modify a model attribute (while retaining its name in serialization), you can do so by overriding the attributes method. (This is, in fact, documented.)

class UserSerializer < ActiveModel::Serializer
  attributes :email, :first_name, :last_name

  def attributes
    hash = super
    hash["boolean_attribute"] = object.boolean_attribute.to_s
    hash
  end
end

Notice that we leave boolean_attribute from the inital attributes call. This is because we’ve specified it explicitly in our custom attributes method. And with this, we’ve serialized our boolean attribute as a string without altering its name. (Note that object refers to the object being serialized.)

If you haven’t had the chance to dig into ActiveModel::Serializers yet, I recommend that you give it a go. This whole “JSON API in Rails” thing is pretty fun.

Listen for Cookie Change

I recently hacked around an interesting problem that involved executing some jQuery after setting several ZIP file download HTTP header fields. My initial thought was to make use of an AJAX post request to set the requisite headers and use the relevant deferred methods to take action on the response. Unfortunately, given the circumstances, this didn’t appear to be a viable option.

Download Complete?

I wanted to take some action (display a success message, in this case) after the download had been “forced.” And, for whatever reason, setting the headers seemed to disorient the script. (I say “disorient,” rather than “halt,” because commands after the header() declarations did execute.) In any case, I needed a different solution.

...
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
...

Eventually, this thought crossed my mind: If I can’t return data from this function (in which the headers are set), I’ll need some other way to communicate the appropriate message to the browser. Then, it occurred to me that this could be a job for cookies.

How the Cookie Crumbles

First, I would set a cookie on the initial page load.

...
setcookie('message', 'none');
...

Then, just before setting the headers in my ZIP download script, I would alter the cookie.

...
setcookie('message', $success_message);
header("Content-type: application/octet-stream");
...

Not complicated, I know. My form post would now take care of the ZIP download forcing and cookie value changing. But where did that get me?

Listen for Cookie Change

Since I wasn’t forcing the browser to reload the page (due to the placement of the new header commands and (probably) a lack of the right knowledge), I would need to actively “listen” for this cookie change in order to trigger the appropriate jQuery. Luckily, someone pieced together a neat little JSFiddle for the occasion. This made things simple.

listenCookieChange('message', function() {
    ...
    addMessage();
    ...
});

With a little effort, I had a solution that worked. It felt good.

As I mentioned, I’m sure there exists a much more elegant solution here. Thinking about these struggles (as I’ve unzipped them) has made this clearer. You live and you learn, I suppose.

First Commit

Actually, this Octopress blog is on its fourth commit; I sought to avoid using “Hello, World” in the inaugural sense. “Pilot” doesn’t do it for me, either, these days – no, I’ll leave the occupancy of that compartment of my mind to the first episode of The Office. In any case, this post marks a new beginning of sorts.

I’d like to leave an entry here from time to time, and I’d like to focus on (1) what I’ve been learning, (2) how I’ve been learning, and (3) why I’ve been learning. I’ll do my best to touch on each of these in every post; you have my word(s). Let us conclude for now, though, for this is merely a placeholder.