Rails: Finding Who Called A Partial

So you’re coding a partial and you want to know which template has pulled it in. The magic word is “@first_render”, which will give you something like “homepage/admin” for the homepage/admin.rhtml template. Trivial, I know, but I couldn’t find any mention of it after much googling, so I decided to output self.inspect and was pleased to find that property. I have no idea how reliable it is, if it will survive to Rails 1.2 and beyond, etc, etc, caveat, disclaimer, etc. I do think developers could benefit if Rails explicitly supported the property … just like knowing who called a function, there are always good reasons to do it, and the Ruby philosophy is to give developers the power to choose what’s good for them.

I’m using the property in a tabbed navigation partial, to determine which is the current page. A classic example of where the temlpate property is useful, since the property is used in a generic way, not as part of some complex “if” loop (viz “if template is leftColumn, make the background pink” etc.)

  1. css_classes = ["templateA", "templateB", "templateC"].map {
  2.   |template| @first_render==template ? "on" : "off"
  3. }

  1. <div class="nav">
  2.   <a class="<%= css_classes[0] %>" href="/controllerX/actionA">The A Thang</a>
  3.   <a class="<%= css_classes[1] %>" href="/controllerX/actionB">The B Thang</a>
  4.   <a class="<%= css_classes[2] %>" href="/controllerX/actionC">The C Thang</a>
  5. </div>

(It could be refactored to use some tag helpers and an associative array mapping actions to css classes.)

How Rails Handles Use of Reserved Keywords, Wow!

I didn’t ever expect to get excited about how a framework handles keywords, but Rails just impressed me big-time. When I tried to create a model named “Activity”, Rails told me it was reserved and then came back with a list of thesaurus terms that might be used instead!. That’s not just opinionated software, it’s downright friendly! Most frameworks don’t bother checking this sort of thing at all, let alone providing helpful “What To Do Now” instructions.

  1. > ruby script/generate model activity
  3.   The name 'Activity' is reserved by Ruby on Rails.
  4.   Please choose an alternative and run this generator again.
  6.   Suggestions:  
  8. Sense 1
  9. activity -- (any specific activity; "they avoided all recreational activity")
  10.       => act, human action, human activity -- (something that people do or cause to happen)
  13. Sense 2
  14. action, activity, activeness -- (the state of being active; "his sphere of activity"; "he is out of action")
  15.        => state -- (the way something is with respect to its main attributes; "the current state of knowledge"; "his state of health"; "in a weak financial state")
  18. Sense 3
  19. bodily process, body process, bodily function, activity -- (an organic process that takes place in the body; "respiratory activity")
  20.        => organic process, biological process -- (a process occurring in living organisms)
  23. Sense 4
  24. activity -- ((chemistry) the capacity of a substance to take part in a chemical reaction; "catalytic activity")
  25.        => capability, capacity -- (the susceptibility of something to a particular treatment; "the capability of a metal to be fused")
  28. Sense 5
  29. natural process, natural action, action, activity -- (a process existing in or produced by nature (rather than by the intent of human beings); "the action of natural forces"; "volcanic activity")
  30.        => process -- (a sustained phenomenon or one marked by gradual changes through a series of states; "events now in process"; "the process of calcification begins later for boys than for girls")
  33. Sense 6
  34. activeness, activity -- (the trait of being active; moving or acting rapidly and energetically; "the level of activity declines with age")
  35.        => trait -- (a distinguishing feature of your personal nature)

It’s interesting…the standard HCI advice for showing an error is to not only explain what’s wrong, but how to fix it. “Tell the user what happened, explain the consequences if it’s not obvious, outline how to fix it, explain what to do if they can’t fix it.” Yet, how often do software tools, like compilers, give you anything more than a terse error message. Sure, it’s important to be concise in some cases, but you could always offer an option, like –verbose, to actually provide a few insights.

The New Ubiquities

Email and the web have traditionally been the two ubiquitous services on the internet (prior to the web, it was email and usenet). Podcasting (and vidcasting/vodcasting) is now becoming another ubiquitous service. The reason I mention this was an interesting quote on BBC news today in a story about the web’s birthday. Despite the story having nothing to do with podcasting, it’s intro’d as follows (@ 25:00):

The world wide web is 15 years old. While podcasting is relatively new, it’s difficult for many of us to remember a time before email and websites.

For a long time, I tried to use games as an example of the difference between the net and the web, to point out to non-techies that the net is more than just surfing. No longer.

There’s another service becoming ubiquitous as well: telephony (IM alone never got past early adopter stage).

In the aforementioned story, the BBC’s futurologist points to mobile as the next big thing. I tend to agree, and this is a case where the “leapfrogging” buzzword will come into full play. So much depends on mobile telephony regulation and the degree of innovation within the telco industry. Right now, mobile internet rates are laughable in most countries, and development platforms remain as fragmented and obscure as ever.

Rails, Selfishness, and Opinionated Patterns

When people talk about their favourite benefit of Rails over framework X in language Y, they’ll usually mention ActiveRecord, Ajax support, etc. But at a deeper level, the thing that really stands out is that Rails is opinonated software. This is where Rails derives its power and agility.

It’s pretty well-understood in software that consistency trumps piecemeal optimisation. Consistency comes from opionated software, piecemeal optimisation comes from design-by-committee. By piecemeal optimisation, I’m talking about something that’s full of good little chunks of local functionality, but falls apart when you use it because everything works differently.

Stated in another way, opinionated software is task-driven, whereas design-by-committee tends to be technology-driven. When DHH says the sky is now red, he’s selfishly refactoring things in such a way that he can work more effectively. I was about to slap quotes around “selfishly”, but the truth is, it really is a selfish act. And therein lies the benefit – it’s often better for me, as an end-developer, to work with a framework that one man (being DHH) has produced for himself than to work with one produced by a committee of agents with a variety of potentially conflicting interests. This, of course, assumes that DHH is talented and that he works on similar things as me.

Caveat: The above is a very crude approximation of the truth which ignores the contributions of many talented core developers, contributors, and feedbackers. And of course, I don’t mean selfish in a malicious sense, I mean it in an “enlightened selfishness” sense.

What’s particularly interesting about opinionated software is that it mirrors the subjectivity of patterns that has been discussed for years, by Richard Gabriel, Jim Coplien, and others (see Patterns of Software). While patterns are sometimes thought of as the endpoint of rational, wiki-ideal-like, trial-and-error, they are actually highly subjective. Indeed subjectivity is a key distinguishing factor between pattern languages and pattern collections.

To appreciate the importance of a pattern language, it is necessary to comprehend the subjective basis of pattern languages. Far from being the objective and exhaustive catalogue of ideas they may initially seem, patterns are based heavily on an underlying set of values. They explain how forces are identified and resolved according to certain principles; in doing so, they are encapsulating a particular approach. Alexander identified, valued, and discarded patterns in a process which embodied his own architectural philosophy (Kerth, 1997).