Call Montréal, Canada 524-949-6869

Blog

Thursday, December 30, 2010

Specifying Behaviour vs Specifying Implementation

At the JRubyConf in Columbus, Ohio last October, Jim Weirich presented "Testing – Why Don't We Do It Like This?". At the end of the presentation he suggested asking two questions to ensure our tests are specifying behaviour rather than implementation:

  1. If I wanted to use this software in my project, what behaviours are important to me?
  2. Could I write this software from scratch using only the tests/specs as guidance?

These are definitely useful questions to ask, rather than blindly writing specs to simply get 100% test coverage. Check the entire presentation below:

Testing – Why Don't We Do It Like This? – Jim Weirich from Engine Yard on Vimeo.

Wednesday, December 29, 2010

Recent Project: Wayne Gretzky Estates

Not all projects need to be complicated! This was one of the simpler, low stress projects (yes they do exist!) of the year, working with creative director Bob Beck at Dynamo. I'm not a huge hockey fan, but who wouldn't want to work on a project with The Great One's name on it. For the tech geeks, Wayne Gretzky Estates is an online store developed using Spree, a Ruby on Rails e-commerce platform. Screen shots below.

Catalog

04-catalog.jpg

Gallery

Gallery

News Index

News Index

News Article

News Article

Monday, December 13, 2010

ShoeDazzle featured on TechCrunch

I had the pleasure working with ShoeDazzle in Los Angeles this summer when they re-developed their shopping platform. ShoeDazzle offers a personalized style service with a celebrity flair. For a monthly subscription fee, you have a choice of a pair of shoes, handbag or jewelry from you own, personalized catalog, handpicked by celebrity stylists. Fun!

This month ShoeDazzle is featured on TechCrunch and described by Jeremy Liew "the most underrated [company] in his portfolio". Checkout the interview below with Brian Lee.

Monday, December 6, 2010

Truncate HTML in Rails

After a bit of searching for a truncation helper for HTML, I found this great gem: truncate_html. It maintains the HTML tags (i.e doesn't strip them out) and supports word boundaries. Nice! Oh, and supports Rails 2.x and 3.x.

Sunday, December 5, 2010

The Mocking Debate Continues

Nick Gauthier recently blogged about "Everything that is wrong with mocking, bdd, and rspec". Nicks' a smart guy, you just need to check out his presentations to understand that. In his post he attempts to demonstrate the brittleness of mocking. While his arguments appear sound at first glance, Pat Maddox presents a well articulated argument. Reading his points on collaborators and protocols gave me a clearer understanding of BDD. I repeat here, but encourage you to check out the comments check out the comments. It's a great debate.

The mock-based example specifies the interaction with the collaborator. It demonstrates that you can pass in any object that responds to #puts(str) and expect it to work.

Your refactoring is valid -- when the output object responds to #puts, #write, #print, and #<<, and implements them all in basically the same way.

You are free to change the internals of a method however you want, but remember that certain changes will have broader-reaching effects than others. Changing how you build up the string to, say, an array of strings that then get joined, should certainly be encapsulated. Changing how you call collaborators is a totally different thing -- you're changing the contract, potentially in a way that's incompatible with existing clients.

Focused examples (or unit tests, or microtests, or whatever) help answer the question, "what do I need to know to use this code?" When there is a collaborator involved, one of the key things to know is the protocol that the collaborator must adhere to. An interaction-based example makes that protocol explicit. Moreover, it establishes a checkpoint. Should you decide to call #write instead of #puts, you have to consider the possible implications to existing code.

I understand where you're coming from. When you run the program, there is no externally visible difference in behavior. That is why we tend to separate the duties of checking program behavior into acceptance tests. Your unit tests then become a place for you to check an object's correctness, which includes its own logic and its interactions with other objects. Don't assume that because the external behavior of the program stays the same, that the behavior internal to objects has stayed the same as well.

Friday, December 3, 2010

Avoid a bloated slug on Heroku by configuring Bundler

This tip was outlined in Heroku's December email newsletter, and wanted to repeat here. It's a must know. You don't need your development and test gems in production, so configure your Heroku application accordingly:


Smaller slug, faster installation and compile times, nice.

Saturday, November 27, 2010

Recent Project: "Aldo's Let's Dance" Fall Campaign

By the lack of blog posts this month, you might have guessed that I've been busy. You're right! I even failed to blog about a launch early this month. But here it is...

I had a great time working with Dynamo, located in the old port of Montreal, on Aldo's fall campaign, "Let's Dance". The concept is simple: upload a video of yourself dancing to Think About Life's Sweet Sixteen and let Internet groupies vote via Twitter, Facebook and/or YouTube. The entries have been fantastic, the traffic through the roof, and voter participate off the charts. It's definitely the most fun I have had all year. Check out the screen shots below and some technical details for those inclined, but better yet visit the site before 6th December to get the full experience before voting ends.

Thanks to Alex (Interactive Director), Jenna (Senior Designer) and Marie (Front-end Integrator) from Dynamo who made this such an enjoyable project to work on.

Home Page

Aldo Let's Dance Home

Gallery

Aldo Let's Dance Gallery

Video

Aldo Let's Dance Video

Registration

Aldo Let's Dance Registration

Technical Details

"Let's Dance" is built using Ruby on Rails, tested with Cucumber and RSpec and deployed on Heroku. The application integrates several different services via Oauth: Twitter, Facebook and YouTube. By using Oauth we are able to track unique votes, as each vote is captured with the voters Oauth ID, but still allow visitors to share videos as many time as they wish.

Video uploads and approvals are managed using YouTube Direct and deployed on Google App Engine. While this saved development time, the open source application does not currently support Internationalization. It was possible to "hack" this in, but it was more time consuming than it should have been. Having said that, it was great to be able to off load all video processing and management to YouTube.

Deploying on Heroku is a huge help with the sudden influx of traffic. With campaign sites, there's no ramp up with traffic, so the application has to handle large amounts from day one. We monitor performance using NewRelic (on-demand application management), to ensure the application has the resources it needs for fast response times.

Need help with you Ruby on Rails application?

Please contact Nicholas Henry at Firsthand Web Design.

Wednesday, November 3, 2010

jQuery toggle issue on Safari, toggle shows, hides, but does not re-show

I was toggling a collection of nested HTML elements which was working fine in Firefox, but not in Safari. Even manipulating the display attribute using the console produced the same result. Even stranger, clicking outside of the element after a toggle made the element appear. After an hour or so trying to identify the issue, I left it to return later with a fresh mind. Before returning I had restarted my Mac. Yes, you guessed it. It was working. Have you come across this issue? Please let me know in the comments.

Thursday, October 28, 2010

CarrierWave, an alternative to PaperClip for Uploading Files in Rails or Ruby Applications

I recently switched to CarrierWave: "Classier solution for file uploads in Ruby for Rack, Rails, Merb and Sinatra". Why? Here's three reasons:

  1. Uploading logic/handling is extracted into a separate class. Hence the tag "Classier solution". It addresses my sensibility for Single Responsibility and separation of concerns.
  2. It maintains a cache across redisplays. Meaning the user does not need to upload a file again, if other fields are invalid on the model.
  3. Dead easy upload from a remote URL.

Definitley give it a try. Anything I have missed? Let me know in the comments.

Wednesday, October 27, 2010

Redmine Estimated Time Summary Plugin

Redmine doesn't provide any summaries/totals for time estimated on issues out-of-the-box. If this is what you need, I highly recommend redmine_estimated_summary plugin.

Friday, October 22, 2010

Rail's ActiveRecord: include vs join

Confused when to use the :include vs. :join option? Remember these points:

  • join does not load the association into association
  • include does, it loads each association into memory
  • include is not compatible with select option
  • use include when the association is referenced
  • example use with join, doing a dynamic count on an association
  • or when the association is not referenced

Thursday, October 21, 2010

ActiveRecord::Base#becomes

An ActiveRecord method I did not existed: becomes.

Returns an instance of the specified klass with the attributes of the current record. This is mostly useful in relation to single-table inheritance structures where you want a subclass to appear as the superclass. This can be used along with record identification in Action Pack to allow, say, Client < Company to do something like render :partial => @client.becomes(Company) to render that instance using the companies/company partial instead of clients/client. Note: The new instance will share a link to the same attributes as the original class. So any change to the attributes in either instance will affect the other.

Web Integrator Application Hand-off Checklist

One scenario in developing applications, is the application is built and then handed off to a Web Integrator to implement the CSS. The other is templates are created and these are integrated by the web developer. This checklist is primary for the first scenario, but is probably applicable to the second. Here is a list of checks you should make before handing off for integration:

  • Demo data: Can the web integrator easily add demo data to the application. This should be done via a script.
  • Translation: If your application is multi-lingual, ensure all strings are in a locale file and the Web Integrator knows how to edit these. Spend some time teaching the Web Integrator on how it works.
  • Test translations: Before an application is translated, run the application in the secondary language to make sure that all "strings" for that language are missing. Check especially for emails static pages and built-in error messages, labels and attributes.
  • Language Switcher: Ensure a language switcher exists and is working.
  • Emails: If your application sends emails, ensure the developer can send and preview these easily. This can be done with the a script to send emails and a preview option via http. Rather than your application send emails, use a email service provider.
  • Minimize custom helpers: Helpers can be a roadblock for a Web Integrator not familiar with Rails. If you do use helpers, have the helper render a partial which can be easily customized.
  • Test accounts: Most applications are not standalone these days. If your application connects with external services such as Twitter and Youtube, ensure test accounts have been setup and can easily be used. You want to encourage the Web Integrator to use these integrations as much as possible. It's a great way to catch bugs!
  • Overlay option: Seen a web site without an overlay these days? Allow your Web Integrator to render a page without the entire layout easily. Passing a parameter along the URI is great way to do this.

Any thing I have missed? Please let me know in the comments.

Tuesday, October 19, 2010

Rails UJS using jQuery results in Unknown File Type/Prompted to save file with IE

I'm developing a Rails 2.3 project with the UJS file for Rails 3. Instead of the remote_form_fortags, I'm adding the data-remote attribute. This was running great on Safari and Firefox, but testing a form post on IE would result in the browser trying to save the file. There are a lot of posts regarding this issue, but none of them worked for me.

The fix ended up being very simple. Upgrade jQuery. The application was using 1.4.2. I upgraded to 1.4.3 and everything worked as it should under IE.

Related posts

Monday, October 18, 2010

Unix History Commands

!! : to run the previous command 
^P : move up through history list, one command at a time. (Up arrow key) 
^N : move down (or Down arrow key). 
!n : run nth command in history list. where n is a number from your history list. 
!n:p : only preview command number n (will not execute the command). 
!string : Run most recent command starting with characters in st

Source

Cached Key for ActiveRecord Collections

Last night I was doing some optimizations on Heroku utilizing Vanish, their reverse proxy server, and wanted to set an etag for an ActiveRecord collection. Basically I wanted to do something like this:

def index
    @videos = Video.published

    fresh_when :etag => @videos
    headers['Cache-Control'] = 'public'
   end

Surprisingly an ActiveRecord collection does not support the cache_key. Fortunately Jim Gay has written a gem, group_cache_key, to resolve this shortcoming. Just add the gem to your Gemfile and bundle install.

Thursday, October 14, 2010

Slow startup with Rspec (1.3.0) and Spork

This is probably network specific, because at my home office things are fine, but on site at a client, Rspec starts up very slow when running against spork. I tracked it down to line 19 in $GEM_PATH/gems/rspec-1.3.0/lib/spec/runner/drb_command_line.rb

DRb.start_service("druby://:0"); \

Change it to...

DRb.start_service("druby://127.0.0.1:0"); \

I think I have seen postings to the Rspec mailing list in regards to this issue. I will try to track them down to add to this post.

Update

It appears this is an OS X related issue. Checkout this thread for more information: http://www.ruby-forum.com/topic/154556. Thank you, Stuart.

Wednesday, October 13, 2010

Ensure all your external assets are SSL too

Just a quick reminder to link all your assets with https:// when they are under SSL. Since libraries such as jQuery are hosted by third parties such as Google, it's easy to forget to use https. When a user accesses a page under https and some assets are not accessed securely, the user will see a dreaded message warning that the page has some unsecured assets.

In Rails I use the request protocol which returns http: or https://

= javascript_include_tag "#{request.protocol}ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"

I have updated my Webmaster Launch Checklist to include this item.

Thursday, October 7, 2010

Pushing specific tags to Heroku

From the Heroku's October Newsletter, I thought that this was very helpful. Tag a release in Git:

git tag -a v1.1

And push it to Heroku:

git push -f heroku v1.1^{}:master

Allow the designer to easily preview Rails application emails

In my post Leave a project how you would like to find it, I discussed how to leave a project with a great README. I added another item to that, how to preview emails. When handing off a project to a designer to skin, an issue that arises is previewing the application emails.

In his Scaling Labs video, Greg Pollack suggests handing of application emails to an email service provider. I think that is a great idea, but sometimes if you are working on a short lived website that might be over kill. So my solution is to create a rake that a designer can easily use. Here's my recipe:

  • Create a separate config/mail.rb environment based on development.
  • Append config.action_mailer.delivery_method = :sendmail to the file.
  • Configure your database.yml with the same settings as your development environment.
  • Write your rake tasks.

Here an (edited) example of the rake task I wrote (lib/application.rake):

desc %{Sends test notification
Must specify RAILS_ENV=mail
EMAIL=you@example.com to specify email address}
    
task :send_notification => :environment do |t|
  registration = OpenStruct.new
  registration.first_name = Faker::Name.first_name
  registration.last_name = Faker::Name.last_name
  registration.email_address = ENV['EMAIL']
  
  CompetitionMailer.deliver_notification(registration)
end

Now run rake send_notification RAILS_ENV=mail EMAIL=nicholas@example.com. Check your email inbox!

Platform notes:

  • Rails 2.3.8
  • Mac OS X

There are other solutions that you may be interested in as well:

  • MockApp: "a native Mac application that embeds its own SMTP server. It also features an e-mail client browser, enabling instant viewing of both raw content and HTML rendering, so you can see how your mail looks when delivered".
  • MailTrap: "A mock SMTP server for use in Rails development".

Wednesday, October 6, 2010

Using rails.js, Rails 3 UJS in Rails 2 application

It took me a while to find these links over the weekend, so I thought I would list them here. I wanted to use the rails.js UJS in a Rails 2 application. I was specifically interested in using jQuery.

I hope you find these helpful. Any other UJS hints for Rails 2? Please add them to the comments.

Tuesday, October 5, 2010

Keeping it fun, knowing when to stop

On Sunday afternoon, I had the pleasure to design and modify my girlfriend's, Alex, MySpace page for her band. It was a really fun experience. Often my work is solitary, programming alone without a pair. Sunday was my first experience for a longtime working with a pair. While it wasn't pair programming, you could describe it as pair design. She had a vision, and I had the technical skill set. While the project was relatively simple, there were a few constraints we were working with: the MySpace interface and my design skill set. Through the afternoon, there were ideas being bounced between us, and refinements moving forward. I loved it.

The hours flew by, and before we knew it it was time for dinner. Alex was keen to keep going since we were so close. I knew in reality that we had another couple of hours to go. So I said, "I want to keep this fun". I knew after a couple of hours, we would be tired and hungry. No more fun.

So we stopped, published what we had, and committed to finishing it the following weekend. It kept it fun.

I think we need to stop more often to keep things fun. Often we just keep going for the sake of finishing something completely. The web is great medium where we can publish work in progress, and come back to refine it. Often we have this notion of only publishing "completed" work. In reality, it's never completed and will always need refinement.

How do you keep it fun? Let me know in the comments.

Saturday, October 2, 2010

Installing Redmine on Heroku with S3 Storage: Step by Step

Update: 15 August 2011This blog post was written almost a year ago. I haven't attempted to install Redmine on Heroku since then, so your milage may vary. I do intend to do an updated version in the future as this has been a very popular post.

I've started using Redmine this year, a project management web application, and I'm a big fan. I'm also a big fan of Heroku for deploying Rails applications. So, you know it makes sense -- deploy Redmine on Heroku! Here's how to do it step by step:

Initial Setup

$ mkdir your-company-redmine
$ cd your-company-redmine
$ git init
$ git remote add redmine git://github.com/edavis10/redmine.git
$ git fetch redmine
$ git merge redmine/1.0-stable
$ rake db:create RAILS_ENV=production

# if you don't have these installed
$ (sudo) gem install rails --version 2.3.5
$ (sudo) gem install rack --version 1.0.1

# setup database locally
$ RAILS_ENV=production rake db:migrate
$ RAILS_ENV=production rake redmine:load_default_data

$ rake generate_session_store

# add .gems
rails --version 2.3.5

$ mkdir tmp public/plugin_assets

# remove from .gitignore
/config/initializers/session_store.rb

$ git add .
$ git commit -m "Initial configuration"

Install Plugins

# install plugins, I like to use giternal
$ (sudo) gem install giternal

# add config/giternal.yml
redmine_heroku:
  path: vendor/plugins
  repo: http://github.com/edavis10/redmine_heroku.git
  
redmine_s3:
  path: vendor/plugins
  repo: http://github.com/tigrish/redmine_s3.git

$ giternal update
$ giternal freeze

$ git add .
$ git commit -m "Adds plugins"

Configure Heroku Plugin

# Remove from .gitignore
/public/plugin_assets

$ rake heroku:setup

Configure S3

# config/s3.yml

production:
  access_key_id: YOUR_S3_ACCESS_KEY_ID
  secret_access_key: YOUR_S3_SECRET_ACCESS_KEY
  bucket: YOUR_S3_REDMINE_PRODUCTION_BUCKET
  cname_bucket: false

development:
  access_key_id: YOUR_S3_ACCESS_KEY_ID
  secret_access_key: YOUR_S3_SECRET_ACCESS_KEY
  bucket: YOUR_S3_REDMINE_DEVELOPMENT_BUCKET
  cname_bucket: false
$ git add .
$ git commit -m "Configures S3 plugin"

Configure Sendgrid for Email

# remove from .gitignore
/config/email.yml

$ heroku addons:add sendgrid
$ heroku config


# configure config/email.yml
production:
  delivery_method: :smtp
  smtp_settings:
    address: "smtp.sendgrid.net"
    port: 25
    authentication: :plain
    domain: "heroku.com"
    user_name: "YOUR_SENDGRID_PASSWORD"
    password: "YOUR_SENDGRID_USERNAME"
$ git add .
$ git commit -m "Configures SendGrid for email delivery"

Deploy to Heroku

$ heroku create your-company-redmine
$ git push heroku deploy

# since we have the database setup locally, lets' push it
$ heroku db:push

Friday, October 1, 2010

Collapsing Margins in CSS

This is one of those rudimentary behaviours in CSS that I need to be reminded of once and a while. Top and bottom margins from adjacent elements will collapse. The element with the larger margin will prevail.

Collasping margins in CSS

Thursday, September 30, 2010

SearchLogic ordering not working: Uses associations default scope for ordering

Came across an interesting issue with Searchlogic. Given the following models:

class Organization < ActiveRecord::Base
  has_many :contacts
  default_scope :order => "name"
end

class Contact < ActiveRecord::Base
  belongs_to :association
end

Contact.search(:first_name_or_last_name_or_assocation_name => "Nicholas", :order => "descend_by_last_name")

The search will actually use the Organization default scope to order the search, i.e. by organization's "name", not contact's "last_name". The fix, unfortunately remove the default scope from the Organization class.

This appears to be an issue with ActiveRecord, not Searchlogic.

Wednesday, September 29, 2010

Status not showing in Redmine in Issues

When you define a new status in Redmine you may notice it's not showing up when you create or edit issues in the drop-down list. To resolve this, you need to modify the workflow under Administration settings to include the new status.

This appears in the FAQ on the Redmine wiki.

Tuesday, September 28, 2010

BlankStatic updated for latest Compass, Haml, Sass; HTML5 Branch

BlankStatic got an update yesterday for the latest Compass, Haml and Sass versions. This means an update to the Gemfile and some changes to the syntax to the Sass files.

An HTML5 branch was added which will work with older version of IE as well with some JavaScript magic.

Thursday, September 23, 2010

Use Terminitor to get your Rails Development work flow setup quickly

For the average Rails Development project I have the following terminal windows setup:

  • Spork for RSpec
  • Spork for Cucumber
  • Rails Server
  • AutoSpec
  • RStakeout task for automatically running Cuke Features

Automatic Workflow Setup

That's a lot of terminals to setup and task to execute! In comes Terminitor to automatically open those windows and run the required tasks. I have the following file in ~/.terminitor/rails-dev.yml:

# Rails Server, Rspec, Cucumber with Spork Setup
---
- tab0:
- tab1:
  - rvm use ruby-1.8.7-p302@default
  - spork rspec
- tab2:
  - rvm use ruby-1.8.7-p302@default
  - spork cuc
- tab3: 
  - rvm use ruby-1.8.7-p302@default
  - script/server
- tab4:
  - rvm use ruby-1.8.7-p302@default
  - autospec -f
- tab5:
  - rvm use ruby-1.8.7-p302@default
  - autocuke

All I need to do is change into the directory of the project and execute:

  terminitor start rails-dev

I keep a blank tab, tab0 so I have a terminal window to play with, otherwise the first "tab" uses that window.

Issues

There was a only a couple of issues I came across which were pretty straightforward to work around. First, it didn't respect my default setup for rvm. I added what Ruby and Gemset to use.

The other issue was that it appeared to screw with by $PATH a bit. It added a space to the last path entry which I think was causing havoc. I just added $HOME to my path, I don't care if it messes with that.

Conclusion

I was definitely getting a little tired opening all the terminal windows for each project. This is well worth checking out.

Tuesday, September 21, 2010

Translating Booleans in I18n files

I got caught out on this today when creating a translation file that included translations for boolean values:

# config/locale/en.yml
  false: No
  true: Yes

t(false) did not translate, i.e. en, false. Ok so to be on the safe side, let's not use Ruby keyword for a key.

# config/locale/en.yml
  false_value: No
  true_value: Yes

t("#{false}_value) translated to false. OK, getting a little close, but not quite what I want.

# config/locale/en.yml
  false_value: "No"
  true_value: "Yes"

t("#{false}_value) translated to Yes. Perfect!

Saturday, September 18, 2010

Update to Firsthand Rails Template

Rails templates are a great way to get your Rails application configured just the way you like it. Today I updated my Rails template to better reflect my current development environment. It's still 2.3.x template, but will be updated when I start developing with Rails 3.x. Some of the highlights included:

  • Bundler for Gem dependencies
  • RSpec and Cucumber for testing
  • Compass, Sass, Haml and Formtastic for stylesheets and views
  • Assumes a Heroku deployment so uses Hassle to work with Sass
  • Removes directories and files that are typically used
  • Adds a default README to be configured

While this template might not work for you out of the box, hopefully it will give you some ideas on how to create your own.

Friday, September 17, 2010

Rails Application Launch Checklist

As a part of my on-going effort to publish checklists on this blog, here is my Application Launch Checklist. Let me know if there's anything missing in the comments.
Configuration and Setup
Optimizations
  • Database optimization (bullet for n + 1 queries, rails_indexes, slim scrooge, query_reviewer)
  • Page Responsiveness (Javascript and CSS caching with Jammit, Sprites, Asset hosts)
  • Background Processing (Delayed Jobs - long running processes, email, file imports and processing, HTTP calls)
Caching
  • Page Caching
  • Action Caching
  • Fragment Caching
  • Query Caching
  • Client-side Caching
  • HTTP Caching
Anything missing from Firsthand Rails Template? Plugins?
NewRelic has a great series on Scaling Rails that reviews techniques for caching and database optimizations.

Install Compass in an existing Rails application with Semantic Blueprint using Sass

compass init rails --using blueprint/semantic --syntax sass

The Other RSpec Methods: #subject, #specify, and #let

Recently I switched to RSpec from Shoulda. This switch was driven mostly by this announcement explaining ThoughtBot's intention in providing matchers for RSpec, rather than a context framework. Here are three highlights from my experience using RSpec over the last month. I call them the other RSpec methods, as their value becomes apparent after using RSpec for a while. I view their purpose as cleaning up setup code located in before blocks.

#let

Get rid of instance variables using #let. Let memoizes a block:

# before "#let"
  before do
    @valid_customer = Customer.new(:name => "Frank Reynolds")
  end

  it "should be valid" { @valid_customer.should be_valid }

  # with "#let"
  let(:valid_customer) { Customer.new(:name => "Frank Reynolds") } 

  it "should be valid" { valid_customer.should be_valid }

#subject and #specify

The subject specifies the object's behaviour that's being described:

subject { Customer.new(:name => "Frank Reynolds") }

 it "should be valid" { subject.should be_valid }

And it doesn't make sense to describe the behaviour ourselves, since RSpec will generate that for us:

subject { Customer.new(:name => "Frank Reynolds") }

 it { subject.should be_valid }

That doesn't read well, so let's use the alias "#specify":

subject { Customer.new(:name => "Frank Reynolds") }

 specify { subject.should be_valid }

But we can use an implicit subject, meaning we don't need to specify the subject (and we revert back to #it):

subject { Customer.new(:name => "Frank Reynolds") }

 it { should be_valid }

Finally, we can also use an implicit subject based on the object we are describing:

describe Customer do
  it { should_not be_valid }
 end

What are your "other" RSpec methods? Let me know in the comments.

Wednesday, September 15, 2010

Custom default attribute in ActiveRecord

When I need a default value for a ActiveRecord attribute often I will resort to using a plugin. But in reality, initializing an attribute in the #after_initialize callback is often the simplest thing that works:

class Tweet
  def after_initialize
    self.message ||= "I'm Tweeting"
  end
end         

Monday, September 13, 2010

Basic HTML Template for Designers to create a Style Guide

When I start a new front-end project coding HTML/CSS I will ask the designer to provide a style guide to outline the typography used through the website. I find when I mark-up the CSS for the typography first, before starting the grid, the overall CSS is cleaner. How do you communicate what elements need to be in the style guide? Well there are some basic elements such as headers, forms and table that I provide in a HTML file that the designer can start with. Then additional typography elements, such as typography in sidebars and call-to-actions are added to the style guide. Are there any elements you think need to be included in my basic HTML file? I like to keep it relatively simple so I don't add things like definition lists, but perhaps I should. Let me know.

Rails Validations can be any ActiveRecord Model Instance Methods

class Customer

  # first_name: string
  # last_name: string

  validates_presence_of :first_or_last_name, :message => "must be provided"

  def first_or_last_name
    first_name || last_name
  end

end

Saturday, September 11, 2010

How to get the options for a named_scope

class Video < ActiveRecord::Base
  named_scope :highest_scores, :order => "score DESC, id"
end

Video.highest_scores.proxy_options # => {:order=>"score DESC, id"}

Friday, September 10, 2010

Configure RMagick gem in a Rails 2.3.x application

# environment.rb
config.gem "rmagick", :lib => 'RMagick', :version => "2.13.1" # version number optional

Autospec problem, autospec exiting without results

A little frustration today with autospec (to clarify, not autospec's fault). I had recently installed RVM and started using gemsets (really this is amazing). When setting a default gemset I installed a bunch of gems including Paperclip 2.3.3. Unfortunately, Paperclip's dependencies include ActiveSupport and installed version 3.0.0. My current default gemspec is setup for rails 2.3.8, I have built a separate one for Rails 3.0.0 on Ruby 1.9.2. For some reason, with ActiveSupport 3.0.0 installed, caused autospec to exit without any results.

(Not running features.  To run features in autotest, set AUTOFEATURE=true.)
loading autotest/rails_rspec
style: RailsRspec

The solution, simply uninstall ActiveSupport 3.0.0 (and any other 3.0.0 Rails dependencies) Paperclip 2.3.3 runs just fine with 2.3.8. This really makes sense since I want to keep a clean 2.3.x environment. To be clear, I had not installed Rails 3.0.0 in this gemset.

BlankStatic Version 1 released with "Bundled" Gems, Onward to Version 2

My template for creating static sites and prototyping templates for web applications and Radiant CMS templates, BlankStatic, has reached a version 1 release. Admittedly BlankStatic hasn't seen much love lately, and I wanted to upgrade the versions of Haml, Sass and Compass it's using. However, this posed a problem for working with older sites using the current version. Enter Bundler.

Bundler allowed me to specify what Ruby Gems my tagged version of the template required in the Gemfile.

# Gemfile
source "http://rubygems.org"

gem "haml", "2.2.0"
gem "compass", "0.8.16"
gem "staticmatic", "0.10.1"

Perfect. A bundle install installed the gems I needed and create the Gemfile.lock that includes specific dependencies and I checked those both into git.

# Gemfile.lock
GEM
  specs:
    cgi_multipart_eof_fix (2.5.0)
    compass (0.8.16)
      haml (>= 2.2.0)
    daemons (1.1.0)
    fastthread (1.0.7)
    gem_plugin (0.2.3)
    haml (2.2.0)
    mongrel (1.1.5)
      cgi_multipart_eof_fix (>= 2.4)
      daemons (>= 1.0.3)
      fastthread (>= 1.0.1)
      gem_plugin (>= 0.2.3)
    staticmatic (0.10.1)
      haml (>= 2.0)
      mongrel (>= 1.0)

PLATFORMS
  ruby

DEPENDENCIES
  compass (= 0.8.16)
  haml (= 2.2.0)
  staticmatic (= 0.10.1)

However, I still had issues with the bin executables when running the server. For example, /usr/loca/bin/staticmatic points to the newer version of the StaticMatic gem, while I need to use an older version. No problem, bundle those executables using bundle exec. Now I can execute the bin/staticmatic preview . in the root of my static site. Super cool.

Now that I have a "freezed" version, I will start working on version 2. This will include an upgrade to the latest dependent gems and changes to the Sass templates to make them compatible with the new syntax.

Thursday, September 9, 2010

How to display Facebook Profile information when using FBGraph Ruby Gem for an Authorized User

When using the FBGraph Gem for Facebook I wanted to display profile information for the logged in user authorized with Oauth2. It wasn't immediately clear to me from the documentation on how to do that.

Once you have a authorized user and a client instance, call:


You can then access various attributes:


Also note there is a fgraph gem as well, don't get them mixed up!

RSpec #stub vs. #stub!

Confused by #stub vs. #stub!? Consider #stub! deprecated and use #stub. #stub is simply an alias for #stub!. #stub! was defined in the API at a time when RSpec's authors weren't clear on the intention of "bang" methods in Ruby. Quoting David Chelimsky's email on RubyForge:

The original method was stub!, which I will confess to introducing, and for the wrong reasons, due to my misunderstanding of the meaning of ! in ruby methods. I recently added stub (with no !) with no particular fanfare, as I don't intend to remove stub! (at least not any time soon). Right now the docs don't make it clear, so I need to fix that - but I'd say that stub() is the method to use and stub!() is there for backwards compatibility.

The confusion is compound in The RSpec Book (B15.0 printing, July 29, 2010) where there is as single reference to #stub! on page 199.

References:

Wednesday, September 8, 2010

Class Methods Called Against Associations in Active Record

Did you know you can call class methods against associations? Admittedly this is a trivial example, but here goes:


Class methods also work against named scopes. I will provide a "good" example of this later in the week.

Ruby Hook Methods

Here is a list of all the hook methods in Ruby. This list is taken from the screencast Some Hook Methods in the The Ruby Object Model and Metaprogramming series.

Method-related Hooks

  • method_missing
  • method_added
  • singleton_method_added
  • method_removed
  • singleton_method_removed
  • method_undefined
  • singleton_method_undefined

Class & Module Hooks

  • inherited
  • append_features
  • included
  • extend_object
  • extended
  • initialize_copy
  • const_missing

Marshalling Hooks

  • marshal_dump
  • marshal_load

Coercion Hooks

  • coerce
  • induced_from
  • to_xxx

Monday, September 6, 2010

Radiant Training Resources and Email Template

For most Radiant projects, I do one-on-one training with the client. This allows them to get familiar with Radiant's administration interface and customizations. I also have a "site" extension, which encapsulates any basic customizations and also add documentation relating to layouts, page types and styles used. This is implemented using the help extension.

Radiant Screencasts

One of the most useful resources I have developed is a series of screencasts that cover a basic Radiant installation and FCKEditor. Please note that these are based on Radiant 8.x. I hope to upgrade these in the near future for Radiant 9.x.

Before the one-on-one session, I send an email to the trainnees, asking them to review the documentation and screencasts beforehand. This is the email template I use:

Email Template

In preparation for you training and for reference at a later date, you have access to online documentation and a series of videos on how to use Radiant, the Content Management System (CMS) for your website.

Documentation

For an introduction to the Radiant CMS:

http://example.com/admin/help

Customizations made to the Radiant CMS for your website:

http://example.com/admin/extension_help/site/all

Videos: Introduction to Radiant

The first series of videos introduces Radiant CMS, how to create and edit pages etc:

http://vimeo.com/album/137118/format:detail

Videos: Using the FCKEditor

The second series is how to use the FCKEditor, a WYSIWYG editor for edit page content. This series describes how to insert images, create links etc.

http://vimeo.com/album/137177/format:detail

Training

I would recommend the participants review the documentation and videos before the training session. All the material will be covered again in the session, but it is helpful to get familiar with Radiant before hand.

The training will cover:

  • An introduction to Radiant CMS
  • Using the FCKEditor
  • Customizations of the Radiant CMS for your website

Training Requirements

Access to a computer with an internet connection will be required.

Please let me know the date and time for the training session and who will be attending. I look forward to helping you get started in maintaining your new website!

Saturday, September 4, 2010

Shopify (eCommerce) Pre-Launch Checklist

Here is a basic pre-launch checklist I use when working on a Shopify Project. Of course this checklist can be used on any type of eCommerce project:

Setup the following:

  1. Email Notifications
  2. Shipping Handling
  3. Taxes
  4. Payment Gateway
  5. Google Analytics
  6. Redirect domain name

And don't forget training the client in using the administration backend. Shopify has a great set of resources for support and training:

The first thing you will probably want to do is help your client understand how to organize their products.

Usability Issue on American Airlines Reward Travel

I wonder how many times some has mistakenly clicked "Start Over" instead of go":

american-airlines.jpg

The solution would be to change the "Start Over" button to a text link and enlarge and relabel the "Go" button. After all the "Start Over" is a secondary to "Go". Here's my solution:

american-airlines-fixed.jpg

Ruby RDoc Example

This is an example RDoc file I sometimes refer to which illustrates documenting classes and methods. Yes I now I should probably move to YARD.

Friday, September 3, 2010

Radiant Releases Now Listed on the Wiki Page

It's now been a week writing my daily stand-up blog posts. I was prefixing the title with "24hrs Firsthand" to identify them as my daily post, but really this seems redundant and just added a lot of noise with no value. After all a blog is a journal, and I suspect readers don't need to know it's my "daily blog post". I will still tag them with stand-up. Now onto some real content...

Radiant Release Notes

Instead of doing my normal wrap-up of yesterday's events, I spent some time this morning listing the Radiant releases on the wiki, with links to release notes, change logs and upgrade notes. I had this in a text file on my local computer -- seemed silly not to share it. I'm sure everybody, new and old to Radiant, will find this very useful.

Thursday, September 2, 2010

Leave a project how you would like to find it

I started a new CMS project yesterday with Radiant. One aspect I am really focusing on is to ensure that all the "other" details are taking care of during the development, so when another developer needs to work on it, they can get started on it as quickly as possible.

The new Bundler and Rails 2.x config.gem have certainly helped with installing dependent gems, but I still think it's beneficial to have a step by step guide in the form of a README file on getting the application running and any other aspects of the application the developer should know about.

GitHub presents the README file of the homepage of the repository.

README file on Github

Please replace the default README file in your Rails or Radiant application (or any other open source application). Here's a basic outline of what you could include:

  • Application setup and database bootstrapping
  • Testing frameworks used and how to run the tests
  • References used on the project (for example, if you used a third-party API, link to those documents)
  • Any other interesting notes that you discovered during development, but would have liked to have known before you got started
  • Populating the database with "demo" data
  • How to easily preview application emails (hint: rake tasks)

Are there any other items that should be in the README? Do you have any links to examples of great README's?

Wednesday, September 1, 2010

Radiant 0.9.1 and Globalize2 Extension

I've started a new project using Radiant. After doing a review of other Ruby on Rails-based CMS projects, Radiant is still my first choice.

This project will be a bi-lingual website and the Globalize2 Extension does a brilliant job of meeting this requirement. You can view the screencast below to get a feel for it's functionality.

However the "master" project repository is not compatible with Radiant 0.9.1. You will need to use this repository instead. I'm thankful for GitHub and forking!

Tuesday, August 31, 2010

What I need from a Content Management System (CMS)

Yesterday I started on a new CMS project. At the beginning of each project I like to reassess the tools that I'm using to make sure I'm not stuck using just what I know. To start, I listed some basic things I want from my CMS:

  • Manages a page tree
  • Can be extended to manage structured data
  • Rich text editor
  • Image Management
  • File Management
  • Link Management
  • User Management

Image and File Management

These are the very basics. I originally had Image and File Management listed in as Asset Management. But I find that these are presented slightly different. Images are presented in a gallery, where "files" such as PDF's are listed in a "file" manager. The Image Gallery and File Manger are accessed directly to upload and organize new assets, and integrated into the Rich Text Editor.

Editor Integration

When inserting an image, this uses the image gallery to chose an image. When adding a link, this will either use the File Manager for assets, or a Page Browser to link to another page on the website. This is what I class as Link Management.

User Management

Most CMS solutions offer sufficient User Management in terms of authentication. However, granting authorization to specific areas of the website is more involved.

Advance Options

These are necessarily "advance", but to go beyond the basics, most website I work on are bi-lingual. Therefore I require some i18n for the administration interface and some method to manage translations.

Other features include search and versioning of content.

Extensible

Finally, it has to be extensible. As mentioned in my post A CMS is Not Out-of-the-box Software, a CMS is not a product until you have tailored it for you client needs. A CMS is a platform. They BrowserCMS team describe this succinctly in their presentation at acts_as_conference. Their slide summarizes this concept:

CMS is not a product, it's a platform

Friday, August 27, 2010

jQuery Cycle Plugin Ghosting with Transparent PNG's in IE

Some one please stop the Internet Explorer madness. I definitely don't want to become the IE go-to-guy. Back to programming Ruby next week, but today was finally getting the jQuery Cycle Plugin working nicely with transparent PNG's.

The issue: IE's handling of transparent PNG's causing ghosting or dark artifacts when animating with the opacity property. It appears I'm not the onlyperson who has come across this problem. So to get IE to play nicely with jQuery Cycle Plugin I need to apply UnitPNGFix to all versions of IE; this hack is typically used for Internet Explorer version 6.x.

This worked well, but I was getting intermittent errors from Cufón when applying the hack:

Attribute only valid on v:image

As suggested by the guys and gals at Media Dog, placing the UnitPNGFix after the Cufón script would resolve the problem. I had no such luck until I explicitly identified which PNG's to "fix" by specifying the classes with "unitPng". Admittedly this what I should have done in the beginning. Once I specified the elements to fix, IE worked flawlessly with the jQuery Plugin.

As a side note, I've never integrated Cufón into a project before. Does it tend to mess up layout in older browsers? When I say older, I mean Internet Explorer. It certainly generates a lot of HTML, and I'm not totally sure if people are aware of the legality converting fonts and having these openly available on the 'Net. Definitely something I need to further investigate.

"Webmaster" Launch Checklist

I have a bunch of checklists that I really need to start sharing on this blog. Here's the first one, the "Webmaster" Launch Checklist. Just some basic things to check before going live with a site. If you have your own online, please link in the comments. If you think there is something I'm missing, please let me know. Admittedly a lot of this is covered by by "blank-static" project, which covers the basics like custom 404 and 500 pages. It's the little things...

General

  • Add Favicon
  • Add robots.txt
  • Validate HTML
  • Custom Meta data for each page: title, meta_description, meta_keywords
  • Setup FOSI Tag
  • Setup Google Account
  • Integrate Google Custom Search Engine (if required)
  • Integrate Google Analytics
  • Add site to Google Webmaster Tools (GMT)
  • Add sitemap to GMT
  • Submit to open source directory
  • Custom 404
  • Monitor 404's, broken links (I use Deep Trawl)
  • Ensure all assets under SSL are linked using https://

Blogs

  • Sign blog up on Technocrati
  • Twitter Link
  • Facebook Link
  • AddThis/ShareThis

Thursday, August 26, 2010

IE7 CSS Madness

Inspired by blogs such as Pivotal Labs and Rails Test Prescriptions I am going to attempt to do a daily recap of yesterday's firsthand experiences. These are going to be short, brief posts. I was going to call it simply Standup but I thought it would be nice to tie the company name in. So here it goes:

Internet Explorer 7 CSS Madness

Yesterday I was thrown into cleaning up some front end CSS for IE7 late in the afternoon. Here's some tricks for kids:

  • The drop-down of a select element in HTML does not expand it's width to display the longest option. Fixed using a JQuery plugin ie-select-width. There is also ie-select-style that allows you to style the select element.
  • IE7 does not play nice with transparent PNG's and the  jQuery Cycle plugin. It tends to acquire the background colour of the parent element. The fix is to add "background: none !important" to the element containing the PNG image in the slideshow.

Saturday, August 21, 2010

Defining Methods in Ruby using #instance_eval

Last week I discussed the differences between class_eval and instance_eval.

I stated there were two basic rules to follow when choosing which method to use:

  1. When the object is a class use class_eval, you will typically be using the def keyword
  2. When the object is an instance use instance_eval

When we use instance_eval to define methods where are the located? The are stored in the instance’s singleton class. I will write more about Ruby’s singleton class in the future, but for now you may want to read Ola Bini’s excellent post on the subject.

Let’s look at an example:

class MyClass; end

my_instance = MyClass.new

my_instance.instance_eval do
  # add the method to the instance's singleton class
  def foo
    "bar" 
  end
end

puts my_instance.foo # => "bar" 

another_instance = MyClass.new

begin
  # since the method exists only on the my_instance singleton class, calling
  # it on another_instance will raise a NoMethodError exception

  puts another_instance.greeting
rescue NoMethodError
  puts "The foo method does not exist" 
end

What happens when we call instance_eval on Class?
MyClass.instance_eval do
  def baz
    "qux" 
  end
end

puts MyClass.baz # => "qux" 

As you can see it defines a class method. I would argue that you should never use instance_eval on a class (although my last post regarding the subject suggested you could). I feel for a beginner in Ruby it may confuse. Stick to class_eval for class objects, and instance_eval for instances. If you need to dynamically define a class method then use this technique:

MyClass.class_eval do

  class << self

    # define .quux as a class method
    #    
    def quux
      "corge" 
    end
  end

  def grault
    "garply" 
  end
end

puts MyClass.quux # => "corge" 
puts my_instance.grault # => "garply" 

A CMS is Not Out-of-the-box Software

This morning I was doing a "Saturday" clean out of some old files and came across this snippet from Namahn regarding Content Management Systems (CMS). I originally came across this around mid-2009:

"Moreover a CMS is almost never a piece of software that comes out-of-the-box. Rather it is a platform/framework for building a custom content application based on an organisation’s needs."

Only for the simplest websites, is a CMS going to work out of the box. I have yet to be involved in a CMS project where there's not some customization required.

"To define the architecture of a CMS and the features it has to offer, you need to figure out how corporate content is created, how it travels through its lifespan, and the uses to which it is put. And because corporate content is created, maintained and used by humans, it is mandatory to define the different interactions people have with documents."

Most of the open source CMS platforms don't address the life cycle of the content. They are good at publishing the content, but never the workflow. Really they should be called Website Publishing Systems (WPS), not Content Management Systems. It would be nice to see more work in this area in the open source realm.

The "white paper" is worth a read if you're trying to get beyond the basics of content management.

Saturday, August 14, 2010

When to use Ruby's class_eval vs. instance_eval

When to use class_eval vs instance_eval? Here are some basic rules to follow:

  1. When the object is a class use class_eval, you will typically be using the def keyword
  2. When the object is an instance use instance_eval

There is an important subtle difference between the two.

  • class_eval changes self and the current class
  • instance_eval only changes self

If you don't need to use def then what should use use? Well you could use MyClass.instance_eval. But as Paolo Perrotta states from Metaprogramming Ruby:

"…pick the method that best communicates our intentions."
class Book
  
  # define a class instance variable
  #
  @books_published = 0

  # define the attr_accessor as a class method
  #
  class << self
    attr_accessor :books_published
  end
    
  def initialize(title)
    @title = title
    Book.books_published =+ 1
  end
end

b = Book.new("Metaprogramming Ruby")

Book.class_eval do
  def introduction
    "Thank you for reading #{@title}"
  end
  
  private
  
  def units_sold
    100_000
  end
end

b.instance_eval do
  puts @title # access an instance variable => Metaprogramming Ruby
  puts units_sold # send a message to a private method => 100000
end

puts b.introduction # => Thank you for reading Metaprogramming Ruby

# I don't care if this is a class or an instance
Book.instance_eval do
  puts @books_published # => 1
end

Wednesday, August 11, 2010

User Story Format

Something I am constantly looking up is a format for user stories. While reading The RSpec Book tonight it remind me to write this down. I thought my blog would be a good place for it.

Connextra Format (named after the company)

As a [stakeholder], I want [feature] so that [benefit].

Popular Variant

In order to [benefit], a [stakeholder] wants to [feature].

Friday, August 6, 2010

Questions asked in a Ruby on Rails Job Interview

Here are some real life Ruby and Rails questions that you maybe asked in a job interview. These are based on my experience in applying for contract positions. I have not provided the answers, I will leave that as an exercise to the reader (as they say).

General Object-Oriented and Programming Questions

  1. What is polymorphism?
  2. What is overriding and oveloading?
  3. What does a test suite contain? (e.g. setup, fixtures, assertions)

Ruby Theory Questions

  1. What is a Singleton Method?
  2. What is the difference between a block, lamda and proc?
  3. What is the super class of Class?
  4. What is the super class of Module?
  5. What is a class variable vs. a constant?
  6. What do you like about Ruby?

Ruby Practical Questions

  1. Print the numbers 1 to 10 in the console
  2. Create a custom method to iterate over an array contain negative and positive numbers and only print the positive numbers

General Algorithm Questions

  1. Reverse an interger, e.g. 12345 => 54321, without converting to a string
  2. Perform a Binary Search on an array of numbers to find a target number

Rails Questions

  1. What is the difference between #destroy and #delete?
  2. What modules make up Rails? (e.g. ActiveRecord)
  3. What is ActiveSupport?
  4. What two extension methods does ActiveSupport contains?
  5. What association methods does ActiveRecord provide?
  6. Which table is the foreign key related in a belongs_to association?
  7. What annoys you about Rails?
  8. Describe a situation where you had to work outside of the Rails stack or customize Rails  to make it meet project requirements?

Database Questions

  1. What is an index?
  2. How is an index implemented?
  3. When would you use an index?
  4. What are the first things to look at with a slow query containing a join?
  5. What is an outer right join?

These questions are ones that I have been asked personally. Please add questions you have been asked in the comments. I'm sure there are some I am missing so I will update this post as they come to mind.

 

Wednesday, July 7, 2010

Ruby's Object#try method

Yesterday I blogged about implicitly testing for nil, relying on Ruby's definition of truth, rather than the explicit Object#nil? to keep code terse.

Here's another example of keeping code terse when handling nil values with Object#try. This is particularly helpful when working with ERB:

# in ERB template
@order.user.name if order.user
The simplified version:
# in ERB template
@order.user.try(:name)

Something I didn't know previously to writing this post, is Object#trysupports arguments similar to Object#send.

Object#try was added to ActiveSupport in Rails 2.3.2.

Monday, July 5, 2010

Keeping your code terse, testing for "nil"

On a recent project, I was seeing many occurrences of this statement:

if !order.user.nil?
  # do something ...
end

While this is correct, it's not idiomatic Ruby. Ruby is a terse language. Let's keep our code terse as well. Consider how Ruby defines truth:

"Ruby has a simple definition of truth. Any value that is not nil or the constant false is true." (Agile Development with Rails, 3rd Edition, pg 319).

This means testing for "nil" is redundant. We can therefore shorten our code to:

if order.user
  # do something ...
end

Nice and clean.

Thursday, May 27, 2010

Email to a Friend: Where to start with Agile Development

Recently a friend emailed me asking how to get started with an agile development methodology. This was my reply (after a little editing to make it more "blog friendly"):

User Stories are the Foundation

For me personally, the foundation of agile is working with user stories. You must have a clear understanding of what user stories are. I would recommend checking out Use Stories Applied by Mike Cohen. This will give you a great foundation. From an estimation point of view, you might want to consider Agile Estimating and Planning by the same author. But not a requirement.

Choose a Methodology

If you’re going to use Scrum (I see that you mentioned “sprints”), to get a good understanding of the lingo and how to plan sprints etc, read Agile Software Development with Scrum

These books should give you a good foundation. They are easy read and not 400 page tombs. You should be able to get throw one in a weekend. They are based on agile after all so they shouldn’t be lengthy reads!

Get Customer Buy-in

The most important thing is that you will need to get buy in from everyone involved. “Agile Software Development with Scrum” provides some good information on this. Maybe a presentation on Scrum would be a good idea to get buy-in. Definitely choose a specific methodology and then customize as required. Since you have no experience, you need a path to follow, and you might run into trouble “just doing agile”. Having a specific methodology (probably not the best noun to use when talking about agile) will be rest assuring to the team.

Make Progress Visible

Of course, the most part is visibility. You want to be able to show visible progress early compared to traditionally managed projects. This comes in deliverables, but also what the priorities are and what people are working on right now. Don’t get too eager to deliver something too quickly. I like Scrum, because sprints are traditionally 30 days, and you never get anything substantially done early than that. Having said that, these guys got something up and running in a week.

If everybody is on site, then a war room with user stories pinned to the wall is a good start; this would be my preference. Otherwise you can use tools such as PivotalTracker or one of the new kids on the block AgileZen.

Manage User Stories

Managing a large collection of user stories is difficult. I think the concept of a story map is a great way to organize them. It gives structure to a loose collection or requirements, which builds confidence all round.

Conclusion

So in conclusion;

  • understand user stories,
  • organize them with a story map,
  • have a war room,
  • use remote user story tools only if required,
  • choose a specific agile methodology (try Scrum),
  • manage expectations.

And remember, make sure you are really doing agile, as it only works if you have all the pieces working together, such as customer buy-in.

Manage expectations, it will take a sprint or two before you are comfortable with the process.

Thursday, March 18, 2010

Getting Rails 3.0 running with “My Stack” on Ruby 1.9.1

I’m pretty excited about Rails 3.0. It really feels like a polished version of the framework, much like Snow Leopard was for Leopard OS X.

At this stage in the game I really don’t want to be starting any new projects with Rails 2.3.5, so I thought I would see if it was possible to get Rails 3.0-beta running with “My Stack”—a set of gems/plugins used on all of my projects. Admittedly, there are probably some others that I should be using, but these are definitely the essentials:

  • haml (with sass)
  • compass
  • authlogic
  • shoulda
  • factory_girl
  • will_paginate

Just to keep things interesting I thought I would throw Ruby 1.9.1 in there to mix things up.

First, stop was to check out railsplugins.org. A registry setup by Engine Yard to track which plugins are Rail 3, Thread Safe, JRuby, and Ruby 1.9 compatible. Let’s see how my stack faired (note, I’m only interested in Rails 3 and Ruby 1.9):

OK, let’s look at each plugin, step by step:

Haml (Confirmed to work)

Installing Haml was pretty straight forward:

# Gemfile
gem "haml", "2.2.21" 

# command line (rails root of course)
bundle install
haml --rails . 

Compass (Confirmed to work)

Install Compass was also straight forward:

# Gemfile
gem "compass", "0.10.0.pre9" 

# command line
compass --rails -f blueprint . --css-dir=public/stylesheets/compiled --sass-dir=app/stylesheets

Authlogic (Unknown to work)

While Authologic is officially “not working”, reports from end users suggest it is. Following along with Ryan Bates screencast, you just need to translate the script/generate commands to rails generate and also check for new options. To setup Authlogic with your application, add it to your Gemfile.

# Gemfile
gem "authlogic", :git => "git://github.com/binarylogic/authlogic.git" 

Shoulda (Unknown to work)

There are no reports regarding shoulda (as there is no version number assigned to, and you can't comment without a version number). Although there is a rails3 branch, it hasn’t been touched since mid-January. Well let’s give it a go and see how far we get:

# Gemfile
gem "shoulda", :git => "git://github.com/thoughtbot/shoulda.git", :branch => "rails3", :group => :test

A couple of options to note. :branch specifies the branch of the git repo, and :group the environment. You won’t be needing shoulda in production.

So how did we get on? Trying rake test... Boom!

DEPRECATION WARNING: RAILS_ROOT is deprecated! Use Rails.root instead. (called from join at ~/.bundle/ruby/1.9.1/bundler/gems/shoulda-b78dbf514bbce3272023d3a4742474857c2eb3c3-rails3/lib/shoulda/autoload_macros.rb:40)
  ~/.bundle/ruby/1.9.1/bundler/gems/shoulda-b78dbf514bbce3272023d3a4742474857c2eb3c3-rails3/lib/shoulda/autoload_macros.rb:40:in `join': can't convert #<Class:0x1297f3c> into String (TypeError)  

OK, let’s remove shoulda gem from:

rm -rf ~/.bundle/ruby/1.9.1/bundler/gems/

And let’s try a more up to date fork. This looks like it:

# Gemfile
gem "shoulda", :git => "git://github.com/bmaddy/shoulda.git", :branch => "rails3", :group => :test

You get this message but it doesn’t appear to be anything to worry about (I hope):

shoulda at ~/.bundle/ruby/1.9.1/bundler/gems/shoulda-87e75311f83548760114cd4188afa4f83fecdc22-rails3 did not have a valid gemspec.
  This prevents bundler from installing bins or native extensions, but that may not affect its functionality.
  The validation message from Rubygems was:
    ["test/rails_root/db/development.sqlite3", "test/rails_root/doc", "test/rails_root/log/development.log", "test/rails_root/log/production.log", "test/rails_root/log/server.log", "test/rails_root/log/test.log", "test/rails_root/test/fixtures", "test/rails_root/test/functional", "test/rails_root/test/integration", "test/rails_root/test/unit"] are not files

And running rake test works. Let’s convert a controller over.

context "create card" do
    setup { post :create, :card => cards(:one).attributes }

    should_change "Card.count", :by => 1
    should_redirect_to("new card") { card_path(assigns(:card)) }
  end  

Almost works, but dies on the should_change marco.

1) Error:
test: create card should change Card.count by 1. (CardsControllerTest):
NoMethodError: undefined method `call' for #<Arel::Value:0x172eba8>
      ~/.bundle/ruby/1.9.1/bundler/gems/shoulda-87e75311f83548760114cd4188afa4f83fecdc22-rails3/lib/shoulda/macros.rb:45:in `block in should_change'
      ~/.bundle/ruby/1.9.1/bundler/gems/shoulda-87e75311f83548760114cd4188afa4f83fecdc22-rails3/lib/shoulda/context.rb:360:in `call'
      ~/.bundle/ruby/1.9.1/bundler/gems/shoulda-87e75311f83548760114cd4188afa4f83fecdc22-rails3/lib/shoulda/context.rb:360:in `block in create_test_from_should_hash'  

Looks like a change in ActiveRecord is causing a few problem there.

Conlusion on Shoulda: OK, it might be the only macro failing, but I think at this stage i will leave shoulda at this point. I’ve filed an issue and if I have some time I will look into it myself.

Factory Girl (Unknown to work)

While the owner says it’s “not working”. A commentator says it does. Let’s give it a go:

# Gemfile
gem 'factory_girl', :git => 'git://github.com/szimek/factory_girl.git', :branch => 'rails3', :group => :test

# command line
bundle install

And convert a controller over to use factories instead of fixtures (yuk!).

# factories.rb

Factory.define :card do |c|
  c.name 'Lorem ipsum dolor sit amet'
end

# cards_controller_test.rb
require 'test_helper'

class CardsControllerTest < ActionController::TestCase

  setup do
    @card = Factory(:card)    
  end

  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:cards)
  end

  test "should get new" do
    get :new
    assert_response :success
  end

  test "should create card" do
    assert_difference('Card.count') do
      post :create, :card => @card.attributes
    end

    assert_redirected_to card_path(assigns(:card))
  end

  test "should show card" do
    get :show, :id => @card.to_param
    assert_response :success
  end

  test "should get edit" do
    get :edit, :id => @card.to_param
    assert_response :success
  end

  test "should update card" do
    put :update, :id => @card.to_param, :card => @card.attributes
    assert_redirected_to card_path(assigns(:card))
  end

  test "should destroy card" do
    assert_difference('Card.count', -1) do
      delete :destroy, :id => @card.to_param
    end

    assert_redirected_to cards_path
  end
end

Yes, it’s a very simple example of using a factory. So there might be some bugs lurking around. But I’m guess it’s safe to say this is usable.

Will Paginate (Confirmed to work)

This looks promising.

# Gemfile
gem "will_paginate", "3.0.pre"  

# command line
bundle install

Again, it’s a simple example, but I think it’s safe to say we’re good to go.

# cards_controller.rb
@cards = Card.paginate :page => params[:page], :per_page => 1

# index.html.haml
= will_paginate @cards

Conclusion

Well it is marked Beta for a reason—and that’s for the gem/plugin ecosystem to catch up. With my limited playing with Rails 3-beta I would be confident writing applications with it, and while most plugins seem to be compatible, I feel a little uneasy doing production projects until there is a broader range of plugins compatible with it. Looks like I will be staying with Rails 2.3.5 a little longer.

Wednesday, March 17, 2010

Get Sass and Compass running on Heroku with Rails 3.0-beta

Heroku is read-only file system causing a little havoc for runtime compilation of Sass files into CSS. In my recent trial of running a Rails 3.0-beta application on Heroku with MRI 1.9.1 I came across this issue.

Doing a google on “heroku sass” will bring you to this post which leads you to sass_on_heroku plugin which is deprecated. The current plugin is Hassle, but unfortunately this hasn’t been touched for a few months. There are some current issues with this plugin and Compass. But all is not lost! Jacques Crocker has forked the plugin and made a fix for this. Get a compatible version of Hassle that works with Compass from his repo.

Now, there’s one change that needs to be made to get Hassle working with Rails 3.0-beta. As Hassle is a piece of Rack middleware, the configuration has changed and must be configured using the Railtie class based on this documentation. Admittedly, this is a little hacky, but gets things going. Placing the Railtie file in it’s own file and namedspace would clean things up.

# init.rb

# Rails 2.3.x style
#
# if RAILS_ENV == 'production'
#   ActionController::Dispatcher.middleware.use Hassle
# end

require 'hassle'

class HassleRailtie < Rails::Railtie
  config.middleware.use Hassle if Rails.env == 'production' 
end    

And, that’s it! With this you should be able to get Sass and Compass running on Heroku with Rails 3.0-beta.

Getting Rails 3.0-beta running on Heroku

I wanted to test out Rails 3.0-beta and see how far I could get with developing an application with my stack of gems/plugins. I hadn’t checked out Heroku either, so it gave me an opportunity to try out their new stacks with Ruby 1.9.1.

First, I installed Rails 3 Beta and RVM outlined in Ryan Bate’s screencast. If you haven’t installed RVM yet, you will be wondering why it’s taken you this long. I did.

Once you have Rails up and running, you can following with their quick start guide. There’s a couple of things to take note when deploying for Rails 3.0-beta, but it’s all pretty straight forward.

As mentioned in the documentation you will need to add the “pg” gem to your Gemfile as Heroku runs Postgres database on their servers; i.e. not MySQL.

  # Gemfile
  group :production do
    gem "pg" 
  end  

By placing it in the “production” group you won’t need to install it locally.

I’m super impressed by Heroku, and look forward to get a production application running on their platform. It’s simply awesome.

Monday, March 15, 2010

Focus Website Content on your Customers' Knowledge Gap

The biggest hurdle when developing a website is producing the content. All of us who have experienced the process of launching a website will probably agree that it was the content development stage that dragged out forever, that delayed the launch. Even deciding what content should be on the site is difficult. Over the last two posts1, I have highlighted the importance on focusing on your customer first, and outlined strategies to identify their needs.

Identify your customer’s knowledge gap

Another strategy is to identify your customers’ knowledge gap. The concept of the knowledge gap was presented by Jared Spool (of UIE fame) in his presentation “What Users Want”2. The knowledge gap is the gap between two points on a spectrum, the current knowledge and the target knowledge.

Picture 1.png

The current knowledge is the information your customer already knows about your business domain: your company, service, product, industry and market. The target knowledge is what your customer needs to know to make a decision.

Spool suggests your website content targets the knowledge gap. It is a wasted effort to develop content before current knowledge and after target knowledge.

How to find the knowledge gap?

A quick start on identifying your customers’ knowledge gap is to create two lists side-by-side. List 20 items your customer knows about what you are trying to sell—their current knowledge. Then, list 20 items your customer needs to know to make a decision—their target knowledge. You can help refine this list by visiting forums where your customers engage, and observe the questions that are being asked.

What is your customers’ knowledge gap?

[1] Create a Sketch of your Customers’ Needs and Ask 20 Questions to Build Customer Empathy

[2] What Users Want

Wednesday, February 10, 2010

Create a Sketch of your Customers’ Needs


Flickr Photo Credit: ruimtevolk

Last week I wrote about Asking 20 Questions to Build Customer Empathy, a quick start guide to Customer-Centered Web Design. This week, I want to expand on that, and help you create a sketch of your customers’ needs.

A “sketch” is a perfect noun for what we want to achieve. From my Mac dictionary:

“a rough or unfinished drawing or painting, often made to assist in making a more finished picture”.

Exactly. We want to make a sketch of your customers’ needs before we start on the finished picture, in this case, your website. This sketch will assist you in developing the finished picture.

Ok, let’s get started. Here are five areas that you can brainstorm to start developing the sketch of your customers’ needs. Brainstorm 20 answers for each area (see Why twenty questions?).

  1. Goals: What problem are your customers trying to solve? Alternatively, what opportunity are they trying to capitalize?
  2. Motiviation: Why are they motivated to use a product or service like yours? Sure consider the typical carrots and sticks1, but also consider other motivating factors such as autonomy, mastery, and purpose2.
  3. Outcomes: What is the successful outcome? Paint a detailed picture of what this looks like.
  4. Pain: What is stopping your customer from solving their problem in their current situation? Think money, attitude, misconceptions, and values.
  5. Emotion: What do they need to enjoy the service or product? Sure, a problem might get solved, but it needs to address the emotional needs of your customer as well. Why can’t it be fun?

Now you have this sketch, what content will you develop for the website that addresses their goals, motivations, outcomes, pain and emotions? How will you structure the website to present this content?

I’m all about finding quick ways to help you shift your focus from what you are trying to sell, to the needs of your visitors, the customers of your website. It doesn’t necessarily mean you need to have a huge external research project. The people in your company, such as sales and support representatives have a huge body of knowledge about your customers that needs to be tapped. Get them involved in this brainstorming process.

[1] http://en.wikipedia.org/wiki/Carrot_and_stick

[2] Dan Pink on the surprising science of motivation

Thursday, January 28, 2010

Ask 20 Questions to Build Customer Empathy


Flickr Photo Credit: horiavarlan

This morning I wanted to write a post providing a quick start guide for Customer-Centered Web Design. The main principle of this technique is to build empathy for your customer before designing your website. When you empathize with your customer, you will understand their goals. When you design your website to meet their goals, you will achieve your business objectives. (The term customer is inclusive of all visitors to your website, including prospects and leads).

Creating provisional or ad-hoc personas (user profiles)[1] was one direction I started with. This would involve brainstorming your customers’ goals, motivations, outcomes, pains and emotions. But as soon as I started that blog post it just didn’t feel quick enough! I’ll keep that for a future posting.

So here’s the super quick start guide for Customer-Centered Web Design:

List 20 questions your customers are asking about the problem they are trying to solve.

Simple, yes? Let’s break this super quick start guide down.

Why questions? At the end of the day that’s why people are searching on the Web. There are even websites dedicated to answering questions such as Yahoo! Answers[2] and Stack Overflow[3]. They are trying to solve a problem. “How do I solve this?” “How do I do that?” “Why is this happening?” Your website should answer the questions your customers have. If it doesn’t, then your customers will go somewhere else.

Why twenty questions? Years ago, I attended a Brian Tracy program called the Phoenix Seminar. In the program, Brian recommended generating twenty ideas when brainstorming. Typically the first ten will be easy, while the last ten will be more difficult. But often the most valuable. Was the first twenty easy? Well try another twenty. No, I’m not being mean. It’s amazing what happens when you start thinking beyond the obvious.

Over the last few weeks I have been assisting with several graphic design and communications companies on proposals. The proposal process always starts with “what shall we do for this website?” For me that always feels like the wrong starting point. The website becomes ego-centric or design-centric (design for designs sake). Quickly brainstorming twenty questions from the customer’s perspective helps build empathy and achieves a website that will be successful for your business.

[1] About Face, Alan Cooper

[2] Yahoo! Answers

[3] Stack Overflow

Sunday, January 3, 2010

Want a simple way to get more out of your time? Try the Pomodoro Technique

About one month ago I started using the Pomodoro Technique, a simple time management tool. The process is simple: pick a task to focus on, set your timer for 25 minutes, and go. The idea is to avoid any other distractions as possible. Don’t check your email. Don’t answer that telephone. If something comes to mind, write it down and return to your focused task. Of course, if the fire alarm starts ringing, I suggest your change your focus.

Once the 25 minutes is up, walk away, take a five minute break and return for another 25 minute “Pomodoro”. After 4 Pomodoro’s, take a longer break (15-30 minutes).

Why am I so hot on this technique?

  1. More mental energy throughout the day: working in 25 minute increments, and taking a five minute break I find that it creates a sustainable pace. Coding does drain the grey matter, well at least for me, but using this technique extends my productive hours later in the afternoon than without it.
  2. Reduces procrastination and anxiety: don’t want to start something? Just try it for 25 minutes. Starting something new or difficult can be accompanied by procrastination and anxiety. For example, writing, hence blogging doesn’t come naturally to me. But break it down in 25 minute chunks makes it hell of a lot easier. Of course getting started is the killer, but I know I can do something for at least 25 minutes. And once I’m started, it’s normally a breeze.
  3. Improves visibility of how you spend your time and track interruptions: being a freelancer, selling my time, obviously time tracking is important. But it also gives me a good feeling that when I’m billing the client, I have given them focused, uninterrupted time. When interruptions occur, these are also tracked and reviewed at the end of the day. The goal of course it to do as many uninterrupted Pomodoros that make sense, and devise strategies to avoid interruptions.

For more information checkout the website. There is also a book written about the technique. While the technique itself is super simple, the book “Pomodoro Technique Illustrated” does give you some insights into why the technique works and dives into topics such as the mental cost of context switching.

There is also a free book in PDF format available online written by the creator.

Oh, and you are probably asking yourself, “Why Pomodoro?” The creator of the technique, “Francesco Cirillo”, used a kitchen timer in the shape of a tomato.

Developing Ruby on Rails applications and custom Content Management Systems in Montréal. Contact Firsthand.