Rails Default Date Gotcha

This had me going for a while!

I wanted to default a field to the epoch, i.e. some decades ago, or older. That’s because a batch process will work on the records with the oldest such field, so setting the field to epoch guarantees they’ll get priority initially.

I had a migration like such:

  1. t.datetime :acted_on, :default => 0  ### BAD

After some debugging, I notice FactoryGirl is setting the field to null. The fix is:

  1. t.datetime :acted_on, :default => DateTime.new ### GOOD

Note it’s DateTime.new for epoch, not DateTime.now, which will be the present time. (And you probably wouldn’t want that, because it would be the time you run the migration, not the time a given record is actually created. If you want creation time, use a before_create callback.)

Login Best Practices for Mobile Web Apps

Walking home, I thought I’d venture to make a meal order via my phone…and without making a phone call. It shouldn’t be an ordeal to do so in 2011, but frankly a sense of learned helplessness means I haven’t even tried before. I know, #FirstWorldProblems, but let’s learn something from it.

Anyway, I pull up my favourite meal delivery service, Hungry House (highly recommended! At least in London.) I simultaneously launch a Market search for a Hungry House app – right or wrong, we know mobile app experience is almost always smoother. Well, no app, but the web page loads…and a bunch of antipatterns emerge.

Instead of documenting login antipatterns, I’ll make this post more useful by turning them around and proposing best practices for mobile web login. Beware it’s all speculative and subjective.

Zen Login Form

Make a simple, mobile-optimised, login form. Make sure it’s easy to click on each field to focus them (there’s only two of them!). Make sure any links (“forgot password”, “sign up”) are far enough away they won’t accidentally be licked.

This is true of all mobile web forms, not just login one. But if your app only works behind a login form, this would be the first one to optimise.

“Keep Me Logged In” should default to On

It’s a mobile phone, not an internet cafe, so yeah. Admittedly, this is trickier in the case of a tablet, but still it’s only a default, I’m not saying “hide the option altogether”. Also, form factor detection ftw.

Don’t Expire the Login Cookie

Okay, this will be controversial. But if mobile web apps are to be a viable alternative to mobile-native apps, they should provide the same login experience. Right now, a majorly overlooked distinction is login expiry. I find myself having to login to Twitter all the time, when trying to tweet from some other web app. But with the Twitter mobile app, I’m always logged in. Basically, mobile-native apps never expire the session. Most of them probably don’t even bother with a session/token, they probably just store the user’s credentials in plain text on the device (just some speculation on my part, based on the “see no evil” principle, given that this data is fairly invisible, being stuck in the app’s data storage.) At least a cookie, if found by someone else, doesn’t compromise the entire account, and can easily be expired.

Keep it Light

Needless to say, don’t load so much that the browser crashes. Repeated browser launches makes users hungry.

Marcin Wichary: You Gotta Do What You gotta Do [Full Frontal Live Blog]

Marcin explains the hacks that went into the Atari 2600, moving from a crappy “tennis” game in 1978 to a somewhat less-crappy Pitfall in 1982, doing things the Atari architects never anticipated. (Covered in “Racing the Beam”) Which would be the same if you showed 1990 TBL the web today.

Google Doodles have gotten bigger over the years … lines of code: 2009: 1, 2010: 5000, 2011: 13000 (thx @suhajdab)

Marcin shows various iterations of the underwater doodle:

On the theme of pragmatism, it went through a bunch of iterations, to get to the point where people would know they can control the water flow, ultimately leading to an explicit handle control. And degrades gracefully to IE6 (choppy, but works) and no-JavaScript (nice image).

We haven’t gone beyond the IE6 graceful degradation…we still have this in HTML5, so it’s not going to go away. WebSocket keeps changing, different audio support, etc. Which means you sometimes have to do what it takes.

Rality of JavaScript is if you don’t do anything that feels a bit nasty, you’re a bit behind. So you have to embrace some of these nasty hacks. With doodles, the endpoint is about doing something with a sense of purpose, not being infatuated with the technology, or, for that matter, the art.

Glenn Jones: Beyond the Page [Full Frontal Live Blog]

Glenn Jones has a wicked talk showing his drag-and-drop and web intent adventures. A lot of this is very tricky and not well documented.

He kicks off with an impressive demo. Pure client-side, he drags elements from one window to another. Once dropped, the element fills with online IDs of the contact, by querying their homepage against the Open Graph API.

It gets even better when he drags a zipfile from explorer to Chrome, and expands it…and then drags from Firefox to Chrome. He also drags a vcard out from the contact to the desktop.

He mentions the drag-and-drop nightmare and walks though the various scenarios: Dragging to desktop, dragging between browsers, etc. You’ll be able to see his code in the slides, but suffice to say,there’s a lot of ninja here. All the APIs are different and the browsers there’s a lot of ninja here. All the APIs are different and browsers vary widely.

One hack worth noting is the rarely used “type” attribute on the “a” link. By programmatically creating a type=’text/vcard’, you can make Firefox download just like Chrome’s new download feature.

On to Web Intents. Glenn has a demo using Web Intents to pick a profile or a list of friends.

  1. <intent action="http://webintents.org/save" />
  2. intent.type="text/x-vcard"
  3. intent.data=card;
  4. window.navigator.startActivity(intent);

Mobile demo

For perspective, he goes way back to Lotus 1-2-3 days…these early DBs and spreadsheets succeeded because accountants suddenly had creative independence, data ownership, and portability. Something the later enterprise movement forgot about.

Nicholas Zakas: Scalable Web Architecture [Full Frontal Live Blog]

Nicholas Zakas is talking about scalable JS architecture.

He begins with a straw poll. Turns out half of the Full Frontal room is working on a Single Page App, right now.

Framework != Library. jQuery? Not a framework. It’s a library you call to perform some limited functionality.

What’s a “module”? Very overloaded term, but Nicholas wants us to think about a module as a block of HTML, CSS, and JavaScript together. Like a widget on the Yahoo! homepage. Modules should be loosely coupled, and this can be achieved with the modules living in a sandbox.

Nicholas identifies a layered architecture, where an application core mediates between independent modules, which use a base library (jQuery etc).

Think of modules as little kids – they can do lots of cool stuff, but need strict supervision: * Hands to yourself (limiting what they can access) * Ask, don’t take * Don’t leave your toys around * Don’t talk to strangers

The Application core manages module lifecycles and mediates between them. There’s also an error handling role, and Nicholas gave a talk about this previously: JS Error Handling.

People are usually too coupled to their base libraries, like jQuery. As Joe Smarr pointed out in a 2007 talk, you’re better off using them as scaffolding, and building modules around them.

img

Rik Arends: Cloud 9 IDE [Full Frontal Live Blog]

Next is Rik Arends, founder/CEO of Cloud 9. (I met Mike and Lieke at Full Frontal 2 years ago, when they were Ajax.org, and subsequently hosted Rik and Ruben at Osmosoft, then worked with them on the Cloud 9 Chrome Web Store app and their Google IO sandbox demo.)

Why Cloud 9?

A lot of editors treated JS as an afterthought, so we needed a proper JavaScript editor. We wanted one that wasn’t overwhelming, but still did more than just basic syntax highlighting and formatting, e.g. refactorings. Rik felt it was important to write a JS IDE in JavaScript; was painful to do something like this in Eclipse.

Also, IDEs don’t need to be ugly or cluttered – they should have a designer feel to it.

Cloud 9 a year ago was not yet as polished, but the initial version was received well and there was enough validation to move ahead and bet the company on it. The team raised venture capital and is setting up in San Francisco.

Demo

Rik live-demoes a Node “Hello World”. Running up the server, checkin to GitHub, deploy to Heroku.

Javascript in the Client …

  • APF – high performance UI library
  • ACE – source code editor in JS, adapted from Bespin
  • Socket.io – real-time socket networking
  • jsDAV – file system layer
  • Connect – HTTP middleware

… And JavaScript in the Server

  • Structured exceptions do NOT fit in NodeJS. A single exception for a single user, if it bubbles up, will blow up the whole server! So can’t use exception in Node the way you use them in JavaScript.
  • Beware of globals too, for the same reason. A single global created for a single user/request will linger. So “use strict” and avoid “closure globals” - even though they’re not truly global, they’ll still linger and are best avoided if possible.
  • Avoid state, preferably have none. The thick client makes this real.
  • Monitoring Node process with “forever”.
  • Log everything to reconstruct bugs. You should be able to work out what state your server was in when the bug occurred.
  • Don’t blindly trust a library or module right now.

Where’s Cloud 9 Going?

The vision is to have the whole thing online; should never have to revert back to the local system to deploy.

  • Collaboration
  • Github Chrome extension – edit GitHub directly
  • Multiple buffers – have multiple files open at the same time
  • Undeclared variables
  • Semantic variables
  • Graphical editing inside the (text) editor – e.g. Color picker when you click over a color picker
  • IE6 support
  • Vim mode :D
  • IDE Mobile

Marijn Haverbeke: Code Editing in the Browser

Live-blogging Marijn Haverbeke, creator of CodeMirror, at Full Frontal.

Code editors:

When create Eloquent JavaScript, Marijn wanted to show code cleanly.

ACE – formerly Bespin – was faster and more portable, making CodeMirror look bad! So CodeMirror 2 is a rewrite based on some of those techniques.

Some performance tricks: * Indexes both by line number and by vertical offset. * Only renders the portion of the DOM you can see, plus a little on either side in case you scroll just a few lines. * Selections are passed back to the original text area.

Hijacking browser key events is tricky, browsers don’t always let JavaScript capture events. Chrome has an open bug to let scripts override keyboard.

Phil Hawksworth: Excessive Enhancement [Full Frontal 2011]

My fellow Osmolumnus Phil Hawksworth talking on Excessive Enhancement …

Phil talks about the power of standards, with a nod to Paul Downey’s The Web Is Agreement and The URL is the Thing.

“The seductive power of the possible”. Phil compares the original, raw, Macdonalds site to the recent beetle.de site. Yes, it’s HTML5, not Flash, BUT:

  • 11mb of images
  • 251 http requests
  • no caching

“As you scroll, it lazily loads some images, the next 4MB of uncached images”

The beetle site arguably doesn’t really provide any more information than the original Macdonalds site. The URLs can’t be bookmarked and it takes an age to load!

Twitter is the next subject of Phil’s scorn! No Javascript? No love.

Now we get to Phil’s main point: Interface shizzle doesn’t have to break the web. His example is GitHub’s use of HTML5 history, with the animated slide effect. He notes you can use Levi Routes as a simple way to manage history (it’s the framework Paul Kinlan developed for our Google IO Talk).

Lots of great slides here, too many to post here, but he’ll be putting up the slideshow later on.

Jeremy Ashkenas: CoffeeScript [Full Frontal 2011 Live Blog]

Live blogging at Full Frontal 2011, where Jeremy Ashkenas is first up, presenting on CoffeScript.

Motivation

Good work is being done inside and outside of the TC39 committee. The next version of JavaScript is an open process, a working mailing list you can get involved with, and there’s a chance to experiment and shape it.

“It’s just JavaScript”: CoffeeScript is not about creating a new language or letting us apply an existing language in a browser.

Bootstrapping

Original version of CoffeeScript was written in Ruby, but as v0.5, it became significant enough to bootstrap it: Ruby builds an initial CoffeeScript compiler, which then compiles the real CoffeeScript compiler. Slightly more complicated, but you get the idea: CoffeeScript is basically written in CoffeeScript.

Language Features

  • No “var”
  • No “function”
  • Significant whitespace
  • Comprehensions:

    1. for stooge in list
    2.     console.log 'hi ' + stooge

  • Block strings and interpolation (works for regex’s too):

    1. """
    2. An old pond
    3. a #{animal} jumps in
    4. the sound of water
    5. """

  • Object-oriented, and unlike normal prototype stuff, you get to call super.
  • Binding “this” to the actual object with =>

How it happens

Instead of waiting for a standards body or a browser to give you the language, you can roll your own today. CoffeeScript uses Jison for parsing, there’s also Pegs if you prefer. A nice tip is “it’s okay to cheat”! CoffeeScript uses a strict tokeniser to disambiguate, making the parsing much easier than if it allowed all sorts of ambiguities.