Tip: Conditional Validations for ActiveRecord

Is isn't always desirable, or even necessary, to validate every attribute in a given model with every save. For example, I recently had to build out a tabbed interface for editing products. Normally, when a user would press save, with the controller code calling update_attributes, errors would appear for attributes outside the current tab.

The need for intelligent, conditional validation begat the following module, which can be included in any ActiveRecord class:



module SelectiveAttributeValidatable

def self.included(base)
base.send(:include, InstanceMethods)

base.class_eval do
alias_method_chain :update_attributes, :check
end
end

module InstanceMethods

# Store the set of attributes passed in to #update_attributes.
def update_attributes_with_check(attrs)
@attrs_to_validate = attrs.keys.map(&:to_s)
update_attributes_without_check(attrs)
end


# Returns true if a given attribute was passed in to #update_attributes.
def should_validate?(attr)
if self.new_record?
attrs_to_validate_on_create.include?(attr)
else
@attrs_to_validate.blank? ||
@attrs_to_validate.include?(attr) ||
self.status == 'ENABLED'
end
end

# This method must be overwritten in the class
# where this module is included. Specify whichever
# attributes you want validated on create:
# ['name', 'sku']
def attrs_to_validate_on_create
[]
end

# Allows the should_validate callback to be thrown.
def method_missing(method, *args)
if method.to_s =~ /^should_validate_([_\w]+)[?]/
return should_validate?($1)
else
super
end
end

end

end



After including this module, you'll need to add conditions to your validations, as follows:



validates_presence_if :description, :if => :should_validate_description?
validates_numericality_of :age, :if => :should_validate_age?


Once you've implemented the conditions on your validation, any call to update_attributes will validate only the attributes included in that call.

Caveat

You probably want to make sure that your objects are eventually valid. In my case, this entails storing an enabled/disabled state on the object. This way, I can specify that when the object is enabled, all of the validations should be in effect.

Ruby Did My Taxes

Over the weekend, like many Americans, I did my taxes. I'm required to file a couple of different Schedule C's for various side-businesses I have, and when it comes time to hunt for deductions, it sure is nice to be a programmer.

I had initially thought that I would be able to download the entire year's bank transactions into a CSV file, but alas, my bank (and many others, I'm finding) only provide 45 days of history. They do, however, allow you to download PDF files of all of your statements, and so there I was staring at thousands of transactions in PDFs, dreading retyping them into Excel.

Enter my skills as a Rubyist. I sought out the PDF::Reader library, which allows you to hook its parsing engine to a custom callback and do what you want with it. This definitely parsed the PDF fine, but I had no context; no idea where I was in my statement, because there's no callback for a "new line" character - it's just a stream of words. I found that if I used Adobe Acrobat to save the files as text-accessible, then I started to have statements I was able to work with.

Now that I had 'lines', I was able to use the power of regular expressions to get the data I needed. The lines I was interested in started with a date and an amount, and the rest was just description for my transaction.

Here's the warts-and-all code I used to compile the year's worth of spreadsheet data. It's truly "quick-and-dirty", but it saved me tons of time. The next step, of course, would be to implement regular expressions against the 'memo' field of these transactions, and pre-suppose categories and deductions based on these patterns. But then again, maybe it's time to just use Quicken and stop waiting until the last minute.



Labels: , ,

Having the right tools for the job

Hmm, so many directions I could go in here. Do I talk about the best OS for the job? The best software toolkit for the job? The best IDE? No, I think I'd rather talk about...screwdrivers.

I've been looking for some new tools for working on my computers for awhile now. I'm of the opinion that most precision screwdriver sets and computer toolkits available in stores are of questionable quality. Well, I was recently trying to open up my Nintendo Wii in order to fix the buzzing noise it was making, and I discovered that I couldn't open it without a tri-wing screwdriver. Upon looking for a nice tri-wing screwdriver, I discovered Wiha Tools. They have a huge selection of screwdrivers. The ones that caught my eye had ESD handles for working with sensitive electronic equipment. They also have the largest selection of precision screwdrivers I've ever seen.

Anyway, I decided to give them a go. They have so many precision screwdriver sets that I couldn't decide which one I wanted, but I did put together a custom set to replace my larger tools. If you need a custom set for computer cases, this is a good place to start. Here's what I got:

  • Drive-Loc VI ESD Handle
  • Tri-Wing #0 x #1 blade
  • Slotted/Philips 1/8 x #0
  • Slotted/Philips 5/32 x #1
  • Slotted/Philips 1/4 x #2
  • 1/4 Nut Driver
  • 3/16 Nut Driver
  • Torx T10xT15
  • Canvas storage pouch

All these items can be found here. I would like to note that if you not looking to put together a custom set, you can probably find their stuff cheaper on Amazon. I just ordered my set, if the quality is good, I will be buying a nice precision set from them as well. If I just spent over $80 on a set that I don't like, you will hear about it.

Oh, and one more thing about Wiha tools..they're made in Germany, and as we all know, Germans always make good stuff.



Labels: ,

Legacy effects

twitter.pngClick to zoom.

"The evil that men do lives after them;
the good is oft interred with their bones"

—Mark Antony, William Shakespeare's Julius Caesar



Labels: , ,

Save Time Launching Programs By Using A Launcher, Quick Launch Or The Superbar

Trying to find a program to launch by browsing through the list of programs can be time-consuming, especially if you juggle applications throughout the day. My first suggestion to overcome this is to drag the program on to your quick launch or dock. Your program is now one click away and will save you time next time you have to launch it.

quicklaunch.jpg

Another method for quickly launching an application is to use a launcher such as Launchy (xp) or Spotlight (Mac). These save you even more time by eliminating the search for the icon on your dock or taskbar as you launch the program by typing instead of clicking.

amarok.png

The third approach is to use the superbar (windows 7). The well thought out new taskbar is very time-saving. You can open an application once, pin it on the superbar and it will always be there when you need it. If it is not open, it opens when you click it, if it is open it goes to the window. It is very intuitive and streamlines the computer use process.

clip_image004_thumb.jpg

Methods like these help trim off time during development, leaving more time to focus on writing code.



Labels: , , ,

An Idea Is Born, And Kept Alive.

nurture375_7i59.jpg

Like a newborn baby, an idea is sensitive and needs special care. If you are not careful, you can actually kill an idea. On the other hand, if you nurture an idea, you can see it from conception to incubation to realization and application.

Here are some links to guide you through the nurturing process that can help you give constructive feedback.

  1. Ways to kill and ways to help an idea: A good list of what to say and what not to say.
  2. How to kill an idea, or help it grow: More suggestions.
If you have any other tips on helping an idea succeed, please share them with us.

Labels: , , ,

Quote of the day

"First there was email. That wasn't fast enough, so everyone started texting. That wasn't enough, so now everyone is Twittering. Before you know it everyone will be on the phone."
--Air America CEO Bennett Zier


Labels:

UX Critic: poor app updates

I'm a regular (some might say addict-level) player of Scrabble on my iPhone. It's a pretty good app, limited in numerous ways but enjoyable enough when I'm whiling away the time.

In March, Electronic Arts issued an update to Scrabble, which I eagerly downloaded. I assumed I'd be getting faster play, better rendering, maybe a few cool new features. But what I got was a few new features and a whole lot of degraded UX.

Here's a handy road map for spoiling your user experience, as shown by EA and Scrabble:

  1. scrabble_icon_old.jpgMake the welcome visuals worse. Scrabble used to have a nice little iPhone app with a prominent S tile (at right--S for Scrabble! aha!). scrabble_icon_new.pngWith the new update, someone felt the need to show the Scrabble™ logo on the thumbnail. Which it does, only it's impossible to read (left). The S tile has shrunk, too, making the whole thing much less prominent than before.
  2. Alter the startup screen. The Scrabble app used to have two play options: Quick Play, which jumps a user into a standard, 1P-vs-CPU, normal-level game; and Custom Play, which listed all the variations (multiplay, easy and hard levels, etc.). The screen now has a single Play icon--sensible enough--followed immediately with a More EA Games button. EA's sales team has actually muscled the options, statistics, and help functions to a spot lower than an ad tile. (I could go on and on here.)
    scrabble_welcome_new.pngscrabble_welcome_old.png
  3. Slow the path to use. Users were once one tap from playing a game, or two via the custom play options, which I used. Now, they're three: tap "Play!" then "Local Play" then another "PLAY" button, this time in a different location. Users have to navigate past the network and multiplayer options, which, while useful, are probably not used often enough to justify their positions.
  4. Make easy things harder. On previous versions, if the app was stopped mid-game, a big "RESUME" button appeared on the home screen, inviting the user back into a game in progress. Smart! If I'm already playing, I should be able to dive right in. But the latest update eliminates that button. Instead, one has to go through the same startup options listed above, and find the game-in-progress there instead.
  5. scrabble_resume_game.pngMake things completely confusing. To resume a game, a message appears that reads: "You have a saved game. Do you wish to resume it? Selecting 'No' will delete it." Below it are two buttons: green YES and red NO. The UI here is thoroughly confusing: it feels like a warning. The same screens that take me to a new game are saying "Wait!" and offering me the option of going to an existing game instead. I almost always want to resume, yet I often aim for the red button, because I feel like I'm in the new-game process by accident rather than resuming my last one. It trips me up every time.
  6. Slow things down. This is purely perceptual, but I'm certain the computer's game play has gotten slower, not faster, in this new version. Yes, it's just ducky that the clever CPU can play four bingoes in six turns as it deep-dives into the dictionary. But slower game play on a handheld device is a kiss of death.

Now, I'm still a regular (probably yeah addict) with my Scrabble game, but I like it a whole lot less, and I'm not going to recommend it as readily as before. Which is a shame--just when they're getting into the social aspect of it, I'm ready to bail. What am I going to play now?



Labels:

Jakob Nielsen Likes Action (Envelope)

By Michael Piastro, Senior IA/UXD

Jakob Nielsen recently featured Ai client Action Envelope in his Alertbox article "Mega Drop-Down Navigation Menus Work Well." The usability guru is a fan of what he is calling "Mega Drop-Down Menus," as opposed to traditional DHTML dropdown menus, which he warns against using. Here is a screen shot featuring the actionenvelope.com Mega Drop-Down from the article:

So: usability guru Jakob Nielsen , whose books, articles, and reports I've read, whose evidence I've cited to clients, and whose influence is hard to miss in the IA/UXD usability pond, likes the mega dropdown Ai implemented for Action Envelope in our last site redesign. By extension, he likes me. He really, really likes me.

Seriously though, it's not all roses and tweets. Mr. Nielsen goes on to advise us not to put GUI widgets or other interface elements "that involve more advanced interaction than simply click-to-go." Then the pain starts:

Action Envelope offers a complete login mini-screen within the navbar's "My Account" drop-down. It would be better to simply have a one-click "My Account" link that takes users to a full-featured page that supports login for existing users. (Better still: put this link in the utility nav, which is where people actually look for it according to eyetracking research.)

Ouch. Here is the offending Mega Drop Down, from the Action Envelope site (the same drop down appears if you mouse over Reorder Center):

Mr. Nielsen's critique sounds like great advice, and problems with mouse over/mouse out scenarios on DHTML menus have bedeviled many a web site user.

But that's where the Mega in the Mega Drop Downs helps-by virtue of size, these dropdowns may be less likely to suffer than these types of issues. And there may be site-specific considerations whereby a login form and a little AJAX in a mega dropdown buys us some functionality that enhances site functionality in a measurable way (namely, log in success, order conversion, repeat orders, and AOV). The only way to know for sure is to implement a solution, and test.

Here is what you would see behind the My Account and Reorder Center Mega dropdowns if you were logged in:


In the original design, these logged in dropdowns would have used AJAX to populate the appropriate data without a page reload once the user logged in (using the same drop down), and keeping the user in context of the current page. In other words, user gets Mega Drop Down with login form, user submits form, user gets relevant My Account/Reorder dashboards in context, in place, and without a page reload.

To understand why this approach was taken, and why it works so well, you'd need to understand Action Envelope's business and typical usage patterns. Action Envelope is largely a business-to-business site. Repeat orders are important and common. Workflow associated with providing artwork for a customized envelope or paper order is important, and typically a customer has one (or a very few) orders that they would wish to reorder, or provide artwork for.

Oftentimes a user will submit an order, receive an email notifying them that they need to provide artwork for their order, and return to the site within a few days. If they are still logged in, a simple mouseover action will reveal their recent order that they need to take action on.

In the previous incarnation of the Action Envelope site (which Ai also designed), the my account link was a small link in the utility navigation, and exhibited a 'standard' behavior. Namely, you click it, you go to a log in screen. Since the redesign, conversion is up, average order is up, and reorders are up. Login success vs failure rate doesn't seem to have changed at all.

While none of these stats can be causally related to our design for the my account and reorder center Mega Drop Downs (we haven't A/B tested the simpler implementation in order to be able to assign causality), our solution is based on the specific needs of the Action Envelope site and its users. This, in itself, is certainly a best practice Mr. Nielsen would recommend. So perhaps Jakob does like Action (Envelope) after all.



Labels: , ,

Pick a card, any card

After much cajoling, poking, and prodding, the office convinced me to perform a magic show at this week's Hamster Time (our Friday afternoon "blow off some web-steam" gathering).

Enjoy the show, part 1, part 2, and the encore.



Labels: ,
Page: 1 2 3 4 5 6 7 8 9 10