Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Monthly Archives: December 2010

Dan Podsedly

New in Tracker: Updated look, Google Accounts sign-in

Dan Podsedly
Saturday, December 4, 2010

Tracker has a new look!

The Tracker team has been busy since the hosting move last month. We’ve shifted our focus from improving Tracker’s performance and stability, to core product enhancement. This update introduces an updated visual design, as well the first wave of usability improvements. We’ve also added some new features, including the ability to sign in to Tracker with your Google Account

Reorganized Drop-down Menus

The Tracker project page (above) has a number of visual changes for improved contrast and readability, but it should still be familiar, and just as easy to use. We did, however, re-organize the various drop-down menus to make finding things more intuitive.

The More drop-down menu allows you to access the less commonly used panels such as charts, releases, history, and any integrations you may have enabled for your project.

The new Project drop-down menu contains project level actions such as changing settings, inviting people, configuring integrations, etc. Finally, the Stories menu allows you to perform actions on selected stories, such as deleting, applying a label, or moving to another project.

The Projects drop-down menu has also moved, it’s now part of the navigation links on the right. In addition to allowing you to switch between projects easily, you can now also use it to access the All Projects page, where you can see all of the projects you’re a member of, grouped by account.

The preference settings for including the current iteration in the backlog panel, and showing the project tabs have moved to your Profile page.

Dedicated Signin Page and Google Accounts

The sign-in form is now on a dedicated, HTTPS-only page. Access it with the ‘sign in’ link in the top right corner of the new home page, or this URL:

https://www.pivotaltracker.com/signin

Tracker now allows you to sign in via OpenID, using your Google Account.

If you’ve used your Google Account email address when you signed up for Tracker, signing in with Google will automatically take you to your existing Tracker account.

Disabling Enter Key When Editing Stories

We’ve also added the ability to disable the automatic saving & closing of stories with the ‘enter’ key, as a new preference on your Profile page. This should make it easier for our Japanese users to use the ‘enter’ key to select from kanji words, for example.

Known Issues and Feedback

This is a fairly major update, especially in terms of the visual design. Please let us know if you discover any issues – by email, posting to Satisfaction, or via @pivotaltracker on Twitter. We plan to address these as they arise, and update the site frequently this week. At the moment, we’re aware of some layout issues in Internet Explorer 7, which will be fixed within the next few days.

As always, we’re looking forward to your feedback!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Tips for writing testable, maintainable page-specific javascript

Pivotal Labs
Thursday, December 2, 2010

I’ve worked on several large Rails apps and seen at least a dozen javascript systems. In this post I’ll describe a few techniques that I’ve seen that consistently make javascript easier to test and maintain. To those of you who write javascript more than I do, these might be old news, but it’s taken me 4 years to learn them!

Add your own document ready method

Let’s say you have a page where you need to add a date picker widget to a text field. Let’s also say that you decide not to write a javascript unit test for this file. You follow the example on the widget’s site and come up with something like this:

$(document).ready(function(){
  $(".date_picker").datePicker();
})

It works, and life is good. Over time the requirements change, and you have to pass in some complex functions to see which dates should be highlighted in the widget so you decide to write a Jasmine test:

describe("adding a date picker", function(){
  it("should add a date picker", function(){
    $("#jasmine_content").html('<input class="date_picker"/>');
    expect($('.date_picker.processed').length).toEqual(1);
  });
});

After watching it fail several times, you try to figure out what’s happening. Then it dawns on you – $(document).ready() fired when the dom was loaded, and then you added more elements to the dom, so they didn’t get whatever happened on document ready.

If instead you create your own custom event on document ready, and then listen for that event in all of your custom code you can avoid this problem. For example:

$(document).ready(function(){
  $(document).trigger("content:loaded")
});

$(document).live("content:loaded", function(){
  $(".date_picker").datePicker();
});

Since you are listening for a custom event, you can trigger that custom event in your javascript specs:

describe("adding a date picker", function(){
  it("should add a date picker", function(){
    $("#jasmine_content").html('<input class="date_picker"/>');
    $(document).trigger("content:loaded");
    expect($('.date_picker.processed').length).toEqual(1);
  });
});

This has the added benefit of giving you an easy way applying the same date picker to inputs that are dynamically added to the page later on.

(thank you Evan Farrar for introducing me to this)

Separate behavior and wiring

The example above is a bit more testable, but in your test since you are firing an event that’s meant to be global, you may still end up getting more code executed than you bargained for. In addition, it’s a pretty high-level test, which often leads to needing lots of setup. To avoid that, you can separate your code from the code that applies it to the page. For example:

var DatePicker = {
  setup : function() {
    $(".date_picker").datePicker();
  }
}

$(document).live("content:loaded", function(){
  DatePicker.setup();
});

Now the spec looks a lot more like unit tests you would write in any other language:

describe("DatePicker#setup", function(){
  it("should add a date picker", function(){
    $("#jasmine_content").html('<input class="date_picker"/>');
    DatePicker.setup();
    expect($('.date_picker.processed').length).toEqual(1);
  });
});

To test that the code is being wired up correctly, all you need to do is write a single spec that spies on DatePicker.setup() then triggers content:loaded. Separating code from wiring makes it easier to extract common code to different javascript files, since the classes that apply behavior are standalone.

(thank you to Rajan Agaskar for introducing me to this)

Make all behaviors idempotent

Taking the example above, let’s say that you dynamically create a textbox on the page after page load and need to apply the date picker to it. After adding the input element you trigger your custom event content:loaded and notice that 2 date pickers now appear on the first input! Oops.

You notice that your date picker widget adds a class called “processed” to each input that it applies to, so you update your DatePicker to ignore these:

var DatePicker = {
  setup : function() {
    $(".date_picker:not(.processed)").datePicker();
  }
}

(thanks to Corey Innis for introducing me to this technique)

Add facades for smaller, non-framework third-party libraries

When working with 3rd party libraries it’s normally a good idea to create a facade for your app so that you can swap out the 3rd party library without changing the code that references it. Whenever I work with 3rd party libraries, especially things like API clients (facebook, twitter, bit.ly) and most gui widgets (date pickers, menus) I like to write facades.

For example, let’s say you use the bit.ly api, which looks something like this:

BitlyClient.call('shorten', {'longUrl': url}, 'Some.function');

A simple facade for this service might look like this:

var UrlShortener = {
  shorten : function(url){
    BitlyClient.call('shorten', {'longUrl': url}, 'UrlShortener.shortened');
  },

  shortened : function(data){
    $(document).trigger("url:shortened", [data])
  }
}

With this, you can easily call UrlShortener.shorten and listen for links that have been shortened, so it’s a bit easier to test and to mock out in tests.

(thanks to Ben Stein for introducing me to facades for API libraries)

Don’t add facades for core framework functions

I make an exception to this when it comes to framework code, such as Rails or jQuery. For some reason, I’ve seen people consistently re-implement event listening behavior like so:

var MyApp = {
  register : function(selector, event, callback) {
    $(selector).live(event, callback);
  }
}

Instead of calling jQuery live in code, you call MyApp.register. I’ve rarely seen the benefit of adding abstraction layers to framework code, but I have experienced the productivity loss of having to learn facades that sit on top of frameworks, and dealing with bugs in those implementations. I recommend just using frameworks like jQuery and Prototype directly.

Don’t create a facade for Google Maps

Google Maps is not a framework, so in theory creating a facade would be a good idea. In practice however, I haven’t seen it work. Unless you are using extremely basic map functionality, you will likely not find feature parity across the major javascript map providers like Yahoo! and Microsoft, so if you have to change providers it’s going to be painful anyway, and adding layers of abstraction will be counter productive.

Summary

In my experience, if you trigger behavior with custom events, separate your code from the wiring and write idempotent behaviors, most of your code will exist behind simple, well-tested objects, and refactoring will be easy. Adding facades for small third party libraries, or third party libraries that are likely to change often, can make it easier to test and maintain your code. By avoiding unnecessary facades for large, common libraries like Google Maps and jQuery you can reduce the number of API’s a developer needs to know without affecting the time it takes to switch should you need to.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Maintainable State Machines Part 2 – don't store state names in the database

Pivotal Labs
Thursday, December 2, 2010

In relational databases it’s common to use foreign keys to reference other tables so that when you make a change to values in the table you maintain referential integrity without paying a performance cost. For some reason, many Rails programmers don’t apply this concept to state machines in ActiveRecord. In this post I’ll describe the benefits of not storing state names in the database.

Let’s say you have a community site that allows users to signup. Further, you need to verify their email addresses. You might start with a class like this:

class User
  state_machine :status do
    state :unverified
    state :verified
  end
end

Over time your community grows and some users stop going to the site. You decide that you are going to retire inactive accounts so that the usernames can be claimed by new users. You decide to add the concept of “active” and “inactive”. You update your class to look like this:

class User
  state_machine :status do
    state :unverified
    state :active
    state :inactive
  end
end

Unfortunately, you decided to store the states as strings in the database, which means that you need to run a migration to update existing users:

class AddActiveAndInactiveToUsers < ActiveRecord::Migration
  def self.up
    execute "update users set status = 'active' where status = 'verified';"
  end
end

But with 27 million users in the database, this query takes the site down for over 15 minutes so you have to schedule it for 3am. Even still, you get bad press for being down. And to think, all this can be avoided by just storing integers in the database!

Some state machine implementations provide easy ways to accomplish this. For example if you use PluginAWeek’s state_machine gem you could write:

class User
  state_machine :status do
    state :unverified, :value => 0
    state :verified, :value => 1
  end
end

Since you store integers in the database, you can easily add a new state and change the name of an existing state without having to migrate data. Having state names in the database is a classic example of dependency inversion, where your code, which doesn’t change very often, relies on a value in a database table, which is likely to change more often.

If your state machine doesn’t support storing values in the database as integers (or guids), I suggest you look into upgrading to one that does, or patching your existing state machine to support integers. You may end up getting one less sleepless night because of it!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Maintainable State Machines Part 1 – scopes and predicate methods

Pivotal Labs
Thursday, December 2, 2010

In this post I’ll point out a few ways to write maintainable scopes and predicate methods on ActiveRecord objects that use state machines.

Imagine you work for a small e-commerce site that deals with various products that could be in stock or out of stock. You might start out with a class that looks like this:

class Product
  state_machine :status do
    state :in_stock
    state :out_of_stock
  end
end

Your CEO says that you should only ever display products that are in stock, so you add a scope and a predicate method to help out with that:

class Product
  scope :in_stock, where(:state => "in_stock")

  state_machine :status do
    state :in_stock
    state :out_of_stock
  end

  def in_stock?
    status == "in_stock"
  end
end

Your site meets with wild popularity, and soon you have a thriving consumer site, an API and a mobile site. You have dozens of places where products are displayed, and all of them show products that are in stock. Then your CEO tells you that the site should now show products that are in stock OR out of stock, but not products that have been discontinued. Further, you have to have this done by tomorrow, because there’s a press release going out.

You have a catalog of 20 million products, and changing the state name will cause the site too much downtime, so you hack together something like this:

class Product
  scope :in_stock, where("state in (?)", %w(in_stock out_of_stock))

  state_machine :status do
    state :in_stock
    state :out_of_stock
    state :discontinued
  end

  def in_stock?
    %w(in_stock out_of_stock).include?(status)
  end
end

It’s not pretty but it gets the job done. Now the term “in_stock” in your domain and in your database mean different things, and getting out from under it may be expensive.

To avoid problems like this, I think it’s a good idea to avoid parallel names in states, scopes and predicate methods. In each piece of the code that needs to inquire about an object’s state, ask yourself “why am I asking about the state of the object?” For example, a page that lists products is asking about state because it wants to know “is this object available for purchase?” whereas the warehouse admin pages might be asking “do we need to reorder this product?” In these cases, you might end up with a class that looks like this:

class Product
  scope :available_for_purchase, where(:state => "in_stock")
  scope :needs_reorder, where(:state => "out_of_stock")

  state_machine :status do
    state :in_stock
    state :out_of_stock
  end

  def available_for_purchase?
    status == "in_stock"
  end

  def needs_reorder
    status == "out_of_stock"
  end
end

In this case, if you need to make a change to the meaning of available_for_purchase you can do so without having to change state names in the database or change code anywhere else in the system. In the beginning you may end up with multiple methods or scopes that point to the same scope, but there are several ways to dry up the implementation of each method to stay DRY.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Standup 12/2/2010

Joe Moore
Thursday, December 2, 2010

Ask for Help

“Recommendations for stripping blank lines before and after a block of text?”

  • In Ruby, "a string".strip will do it.
  • Regex recommendations?

Interesting Things

  • If you need to change the author on your git commit message, use

    git commit --amend --author=username

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (778)
  • rails (113)
  • testing (86)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (54)
  • techtalk (44)
  • rspec (38)
  • activerecord (29)
  • productivity (29)
  • gogaruco (29)
  • ironblogger (29)
  • git (28)
  • nyc (27)
  • rubymine (25)
  • mobile (22)
  • bloggerdome (20)
  • cucumber (20)
  • process (19)
  • pivotal tracker (19)
  • jasmine (19)
  • design (18)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • tracker ecosystem (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • selenium (12)
  • css (12)
  • goruco (12)
  • bundler (12)
  • tdd (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • rubygems (9)
Subscribe to Community Feed
  1. ←
  2. 1
  3. 2
  4. 3
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >