This site provides the following access keys:

Brandan Lennox's

Articles : Page 1

Machinist and :validates_uniqueness_of

I’ve lately been having a problem with Machinist while running specs on models using :validates_uniqueness_of. Sometimes an example will fail with a spectacularly unhelpful “Item is invalid” error message when it ran fine just moments before.

I eventually discovered that when an example fails, Machinist doesn’t always destroy all the records it created. This means that data may be left in your test database between examples or invocations of your spec task (if you’re using script/spec). I had been solving this problem by emptying a few important tables in a before(:all) block, but that destroys fixtures that other specs may depend on. So I couldn’t do that anymore.

The problem actually lies with Sham. It will attempt to generate unique values for the lifetime of a single invocation of a spec, but one of its selling points is replicability. Each invocation of a spec results in the same sequence of values for a given attribute. So if the first User generated by Machinist gets the login “buntaluffigus,” and the example fails for some reason, then that user persists to the next run of the spec, at which point Sham will generate the login “buntaluffigus” again, and assuming User logins must be unique, this new model will fail validation and you may simply see that some “Item is invalid.” Sucko.

So blah blah blah, ultimately I had to monkey patch Machinist::Lathe to check for any attribute who :validates_uniqueness_of itself. It depends on Christopher Redinger’s validation_reflection plugin and this file in spec/support:

# spec/support/machinist_monkey_patches.rb
module Machinist
  class Lathe
  
  private
  
    def generate_attribute_value_with_uniqueness_check(attribute, *args, &block)
      value = generate_attribute_value_without_uniqueness_check(attribute, *args, &block)
      if attribute_must_be_unique?(attribute)
        while object.class.first(:conditions => { attribute => value })
          value = generate_attribute_value_without_uniqueness_check(attribute, *args, &block)
        end
      end
      value
    end
    alias_method_chain :generate_attribute_value, :uniqueness_check
    
    def attribute_must_be_unique?(attribute)
      object.class.reflect_on_validations_for(attribute).detect { |v| v.macro == :validates_uniqueness_of }
    end
  end
end

Now all my examples run like they’re supposed to, regardless of fixtures or previous failures or the position of Ares in the fourth quadrant. YESSSSSS.

I Could Design for Apple

I’m updating my résumé right now and decided to look through some Pages templates for ideas. This is how it looks in “San Francisco”:

My résumé in the San Francisco template

Helvetica Neue? Magenta accents? Black on white? This looks so familiar…

HTTP 409 for Fun and Profit

Here’s something interesting I recently discovered. HTTP/1.1 defines a 409 status code indicating a conflict that the client is expected to resolve:

The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required. W3.org

By interpreting that only a bit leniently, I’ve decided to start blocking Internet Explorer 6 on my personal projects. In essence, your shitty browser is in conflict with my impeccable code, and I expect you to resolve this conflict. KTHX!

How Do I Break This to You…?

Here’s the error page I render on the Dekaplan site (which is a bit of a joke in itself anyway):

Example of an HTTP 409 error page“Internet Explorer does not work with this site.”

(I’m using Safari with a spoofed user agent string in this screenshot.)

Carefully worded so as to place the blame squarely on IE, the page also suggests a fix: download a better browser. I purposely don’t suggest upgrading IE, since that’s hardly an improvement.

It’s pretty simple to implement. In Rails, it’s a before_filter in ApplicationController:

class ApplicationController < ActionController::Base
  before_filter :block_ie
  private
    def block_ie
      if request.headers['HTTP_USER_AGENT'] =~ /MSIE 6/
        render :template => 'errors/409.html.haml', :layout => 'error', :status => 409
        return false
      end
    end
end

PHP could do something similar in a globally included script.

Too Far?

Is this going to piss people off? Yeah. I’ve already confirmed that. Several friends couldn’t access the Dekaplan site from work. They either stealth-installed Firefox or waited until they got home to look at the site.

There’s really no way to the content without spoofing your user agent string, and if you know how to do that, you probably aren’t using IE6 anyway. So IE6 users are pretty much completely blocked out. But:

  1. None of my sites get any traffic from any browser anyway.
  2. It’s time to start pissing people off if we want them to move away from IE6.

Gentle prodding hasn’t proven very effective. IE6 still commands 20% of the browser market, with IE8 just behind it and IE7 still holding onto 15% almost a year after the release of its successor. Yes, it’s bull-headed to block content from your visitors, but it’s just as silly to hang on to a decade-old browser. Somebody has to give, and I’ve decided it’s not going to be me anymore.

I Like John Nack

Photoshop’s Principal Product Manager John Nack, responding to comments on one of his recent blog entries:

Wow, it only took you guys eight years to come up with this idea?

[Way to look at the bright side, dude. —J.]

Snarky! I like it!

Now if you’d only get a few more things right like using the default Mac OS installer and using the rest of the default Mac UI. I’m still using CS3 and dread seeing what UI atrocities you come up with for CS5.

[Nice attitude, man. Endless negativity makes it really easy for people to tune out “Mac fanatics” (“They’ll just bitch and hate us no matter what”), and that makes it harder for me to do my job. —J.]

John has a good point. If you’re always complaining, people stop listening. But considering Adobe has to port all their Carbon code to Cocoa pretty soon, could they be working on a major UI overhaul?

You may hate me for my comments, ok. But i don’t like Adobes lazyness and lagging behind with implementations or simply screwing and bloating up things with new uneccesary components.

[So, Adobe is bloated and lazy, but you want us to add more functionality to match the FCP KBSC editor that doesn’t match long-standing Photoshop functionality? Okay. —J.]

Same applies for “Inspector” or how apple call them: “HUD

What you guys are waiting for?

[How about a cycle in which we’re not mandated to do an enormous amount of work with very little customer benefit? —J.]

The classic software developer’s paradox: add more features, but make it simpler to use.

I’m glad that Nack is confident enough to speak his mind on his blog. That’s rare in a world of corporate blogs full of innocuous and meaningless marketing bullshit.

That said, I recently ditched Photoshop for Acorn, and I couldn’t be happier.

← Newer articles